关于python:从类外部的现有方法创建staticmethod?(unbound method错误)

Create staticmethod from an existing method outside of the class? (“unbound method” error)

在定义类之后,如何使类方法成为静态的?换句话说,为什么第三个案例失败了?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> class b:
...  @staticmethod
...  def foo():
...   pass
...
>>> b.foo()
>>> class c:
...  def foo():
...   pass
...  foo = staticmethod( foo )
...
>>> c.foo()
>>> class d:
...  def foo():
...   pass
...
>>> d.foo = staticmethod( d.foo )
>>> d.foo()
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with d instance as first argument (got nothing instead)


在定义类之后,foo是一个未绑定的方法对象(一个将函数绑定到类的包装器),而不是一个函数。包装器将尝试将类(self的一个实例作为第一个参数传递给函数,因此它抱怨您没有给它一个实例。

staticmethod()实际上只应与函数一起使用。虽然类仍在定义中(如在您的bc中),但foo()仍然是一个函数,因为方法包装器在类定义完成时应用。

可以从未绑定的方法对象中提取函数,应用staticmethod()并将其赋回类。

1
2
3
4
5
class d(object):
    def foo():
       pass

d.foo = staticmethod(d.foo.im_func)

在Python3中,没有未绑定的实例方法(存储在类中的方法是普通函数)。所以您的原始代码在python 3上实际上可以正常工作。

在python 2和python 3上工作的方法是:

1
d.foo = staticmethod(d.__dict__['foo'])

(它还避免创建和丢弃方法包装器。)


必须传递函数,而不是未绑定的方法。

1
2
3
4
5
6
>>> class d:
...   def foo():
...     pass
...
>>> d.foo = staticmethod(d.foo.im_func)
>>> d.foo()