将外部函数分配给Python中的类变量 [英] Assign external function to class variable in Python
问题描述
我试图将在其他地方定义的函数分配给类变量,以便以后可以在实例的方法之一中调用它,如下所示:
I am trying to assign a function defined elsewhere to a class variable so I can later call it in one of the methods of the instance, like this:
from module import my_func
class Bar(object):
func = my_func
def run(self):
self.func() # Runs my function
问题在于此操作失败,因为执行self.func()
时,实例将作为第一个参数传递.
The problem is that this fails because when doing self.func()
, then the instance is passed as the first parameter.
我想出了一个办法,但是对我来说似乎很丑陋,有人可以替代吗?
I've come up with a hack but seems ugly to me, anybody has an alternative?
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()
()
编辑:行为与内置函数不同!
The behavior is different with builtin functions!
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
推荐答案
Python函数是 descriptor 对象,当类中的属性访问它们时,实例将它们绑定为方法.
Python functions are descriptor objects, and when attributes on a class accessing them an instance causes them to be bound as methods.
如果要防止这种情况,请使用 staticmethod
函数将函数包装在不绑定到实例的其他描述符中:
If you want to prevent this, use the staticmethod
function to wrap the function in a different descriptor that doesn't bind to the instance:
class Bar(object):
func = staticmethod(my_func)
def run(self):
self.func()
或者,通过方法的__func__
属性访问未绑定函数:
Alternatively, access the unbound function via the __func__
attribute on the method:
def run(self):
self.func.__func__()
或直接转到class __dict__
属性以完全绕过描述符协议:
or go directly to the class __dict__
attribute to bypass the descriptor protocol altogether:
def run(self):
Bar.__dict__['func']()
对于math.pow
来说,它不是 Python 函数,因为它是用C代码编写的.大多数内置函数都是用C编写的,大多数不是描述符.
As for math.pow
, that's not a Python function, in that it is written in C code. Most built-in functions are written in C, and most are not descriptors.
这篇关于将外部函数分配给Python中的类变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!