如何获得未绑定的类方法?
class Foo:
@classmethod
def bar(cls): pass
>>> Foo.bar
<bound method type.bar of <class '__main__.Foo'>>
编辑:这是python 3.很抱歉让人感到困惑。
答案 0 :(得分:17)
Python 3没有未绑定的方法。暂时忘记classmethod
s,看看这个:
>>> class Foo:
... def baz(self): pass
>>> Foo.baz
<function __main__.baz>
在2.x中,这将是<unbound method Foo.baz>
,但3.x没有未绑定的方法。
如果你想从绑定方法中获取函数,那很容易:
>>> foo = Foo()
>>> foo.baz
<bound method Foo.baz of <__main__.Foo object at 0x104da6850>>
>>> foo.baz.__func__
<function __main__.baz>
以同样的方式:
>>> class Foo:
... @classmethod
... def bar(cls): pass
>>> Foo.bar
<bound method type.bar of <class '__main__.Foo'>>
>>> Foo.bar.__func__
<function __main__.bar>
2.x中的事情更有趣,因为实际上是未绑定的方法。您通常无法看到未绑定的classmethod
,因为重点是它们在类创建时绑定到类,而不是保持未绑定状态,然后在实例创建时绑定到每个实例。
但实际上,未绑定的方法只是instancemethod
为无的im_self
。所以,就像你可以这样做:
class Foo(object):
def baz(self): pass
foo = Foo()
bound_baz = foo.baz
unbound_baz = new.instancemethod(bound_baz.im_func, None, bound_baz.im_class)
请注意,bound_baz.im_func
是3.x中bound_baz.__func__
的2.x版本,但new.instancemethod
没有3.x等效版本。
文档说new
已弃用types
,兼容3.x兼容性,事实上,您可以在2.x中执行此操作:
unbound_baz = types.MethodType(bound_baz.im_func, None, bound_baz.im_class)
但这在3.x中不起作用,因为MethodType
不接受class
参数,并且不允许其instance
参数为None
。而且就个人而言,当我做的事情明确是2.x而且无法移植到3.x时,我认为使用new
会更清楚。
无论如何,考虑到2.x中的课程,你可以这样做:
class Foo(object):
@classmethod
def bar(cls): pass
bound_bar = Foo.bar
unbound_bar = new.instancemethod(bound_bar.im_func, None, bound_bar.im_class)
如果你打印出来,你会看到:
<unbound method type.bar>
或者,使用您的示例,使用旧式类:
class Foo:
@classmethod
def bar(cls): pass
<unbound method classobj.bar>
是的,也许这对于旧式课程im_class
的{{1}}是classmethod
可能有点作弊,即使那不是classobj
,但是在所有常见的用例中,似乎最合理的方式是使旧式和新式类的工作方式类似。