Python:获取未绑定的类方法

时间:2013-01-29 02:21:07

标签: python python-3.x

如何获得未绑定的类方法?

class Foo:
    @classmethod
    def bar(cls): pass

>>> Foo.bar
<bound method type.bar of <class '__main__.Foo'>>

编辑:这是python 3.很抱歉让人感到困惑。

1 个答案:

答案 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,但是在所有常见的用例中,似乎最合理的方式是使旧式和新式类的工作方式类似。