2016-06-29 29 views
8

Tôi cố gắng để gán một hàm được định nghĩa ở đâu đó cho một biến lớp vì vậy tôi sau này có thể gọi nó là một trong các phương pháp sơ thẩm, như thế này:Gán chức năng bên ngoài để biến lớp trong Python

from module import my_func 

class Bar(object): 
    func = my_func 
    def run(self): 
     self.func() # Runs my function 

Các vấn đề là điều này không thành công vì khi thực hiện self.func(), thì cá thể được chuyển thành tham số đầu tiên.

Tôi đã đến với một hack nhưng có vẻ xấu xí với tôi, ai cũng có một sự thay thế?

In [1]: class Foo(object): 
    ...:  func = lambda *args: args 
    ...:  def __init__(self): 
    ...:   print(self.func()) 
    ...: 

In [2]: class Foo2(object): 
    ...:  funcs = [lambda *args: args] 
    ...:  def __init__(self): 
    ...:   print(self.funcs[0]()) 
    ...: 

In [3]: f = Foo() 
(<__main__.Foo object at 0x00000000044BFB70>,) 

In [4]: f2 = Foo2() 
() 

Chỉnh sửa: Hành vi khác với chức năng dựng sẵn!

In [13]: from math import pow 

In [14]: def pow_(a, b): 
    ....:  return pow(a, b) 
    ....: 

In [15]: class Foo3(object): 
    ....:  func = pow_ 
    ....:  def __init__(self): 
    ....:   print(self.func(2, 3)) 
    ....: 

In [16]: f3 = Foo3() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-16-c27c8778655e> in <module>() 
----> 1 f3 = Foo3() 

<ipython-input-15-efeb6adb211c> in __init__(self) 
     2  func = pow_ 
     3  def __init__(self): 
----> 4   print(self.func(2, 3)) 
     5 

TypeError: pow_() takes exactly 2 arguments (3 given) 

In [17]: class Foo4(object): 
    ....:  func = pow 
    ....:  def __init__(self): 
    ....:   print(self.func(2, 3)) 
    ....: 

In [18]: f4 = Foo4() 
8.0 

Trả lời

13

Hàm Python là descriptor objects và khi thuộc tính trên lớp truy cập vào một cá thể, chúng sẽ bị ràng buộc làm phương pháp.

Nếu bạn muốn ngăn chặn điều này, sử dụng staticmethod function để bọc các chức năng trong một mô tả khác nhau mà không liên kết với các trường hợp:

class Bar(object): 
    func = staticmethod(my_func) 
    def run(self): 
     self.func() 

Hoặc truy cập vào các chức năng không liên kết thông qua các thuộc tính __func__ trên phương pháp:

def run(self): 
    self.func.__func__() 

hoặc đi trực tiếp vào thuộc tính lớp __dict__ để bỏ qua giao thức mô tả hoàn toàn:

def run(self): 
    Bar.__dict__['func']() 

Đối với math.pow, đó không phải là hàm Python, ở chỗ nó được viết bằng mã C. Hầu hết các hàm dựng sẵn được viết bằng C và hầu hết không phải là các bộ mô tả.

+0

Khối mã cuối cùng bị lỗi ('Đối tượng thanh không có thuộc tính Bar') và nếu tôi xóa' tự' thì tôi nhận được 'TypeError: phương thức unbound phải được gọi với đối số đầu tiên ' – astrojuanlu

+0

@astrojuanlu: ah, yes , xin lỗi, Python 2. Tôi sẽ cập nhật tùy chọn đó để bỏ qua giao thức mô tả. –

+0

Hoạt động ngay bây giờ, cảm ơn! – astrojuanlu

Các vấn đề liên quan