在Python中将外部函数分配给类变量

ast*_*nlu 14 python oop python-2.x

我试图将其他地方定义的函数分配给类变量,以便稍后我可以在实例的一个方法中调用它,如下所示:

from module import my_func

class Bar(object):
    func = my_func
    def run(self):
        self.func()  # Runs my function
Run Code Online (Sandbox Code Playgroud)

问题是这失败了,因为在执行时self.func(),实例作为第一个参数传递.

我想出了一个黑客,但对我来说似乎很难看,有没有人可以选择?

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()
()
Run Code Online (Sandbox Code Playgroud)

编辑:内置函数的行为不同!

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
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 19

Python函数是描述符对象,当访问它们的类的属性导致它们被绑定为方法时.

如果要防止这种情况,请使用该staticmethod函数函数包装在不绑定到实例的其他描述符中:

class Bar(object):
    func = staticmethod(my_func)
    def run(self):
        self.func()
Run Code Online (Sandbox Code Playgroud)

或者,通过__func__方法上的属性访问未绑定的函数:

def run(self):
    self.func.__func__()
Run Code Online (Sandbox Code Playgroud)

或者直接转到class __dict__属性以完全绕过描述符协议:

def run(self):
    Bar.__dict__['func']()
Run Code Online (Sandbox Code Playgroud)

至于math.pow,这不是Python函数,因为它是用C代码编写的.大多数内置函数都是用C语言编写的,大多数都不是描述符.

  • @astrojuanlu:`math.pow`不是普通的Python函数,它不是描述符对象.并非所有内置函数(用C代码编写)都是描述符. (2认同)