使用 python 2.7 class 变量作为函数

Using python 2.7 class variable as a function

我正在尝试将 python class 变量用作函数,使用类似于以下代码的内容:

class A(object):
    func = None
    @classmethod
    def class_init(c,f):
        c.func = f
    def go(self, p):
        A.func(p)

def my_print(p):
    print(p)

A.class_init(my_print)
a = A()
a.go('AAA')

当 运行 它使用 python3 时,一切都按预期工作并且打印 AAA

使用python2,抛出TypeError异常:

TypeError: unbound method my_print() must be called with A instance as first argument (got str instance instead)

似乎 python2 需要一个 class 实例,就好像 A.func 是一个对象方法。

是什么导致了 python2 和 python3 之间的这种不同行为?

有没有办法“告诉”python 将 A.func 作为非对象方法处理?

[我可以想到像将 A.func 保存为列表这样的解决方法,意思是 class_init 中的 c.func = [f]go 中的 A.func[0](p),但是会想了解这种行为的核心原因以及是否有巧妙的解决方案]

由于您要添加的函数没有将 class 实例或 class 作为其第一个参数,显然您正在添加一个静态方法 — 因此您必须明确告诉Python 这就是您通过手动调用 built-in staticmethod() 函数所做的事情。

class A(object):
    func = None

    @classmethod
    def class_init(c, f):
        c.func = staticmethod(f)  # Assume function type.

    def go(self, p):
        A.func(p)

def my_print(p):
    print(p)

A.class_init(my_print)
a = A()
a.go('AAA')  #-> AAA
my_print(42)  # -> 42

或者,您可以在 class 之外使用它作为函数装饰器,如下所示。这样做的一个缺点是它只能通过 class 或 class 实例调用。

class A(object):
    func = None

    @classmethod
    def class_init(c, f):
        c.func = f

    def go(self, p):
        A.func(p)

@staticmethod
def my_print(p):
    print(p)

A.class_init(my_print)
a = A()
a.go('AAA')  # -> AAA
my_print(42)  # -> TypeError: 'staticmethod' object is not callable