18

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

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

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

编辑:这是python 3。很抱歉造成混淆。

4

1 回答 1

24

Python 3 没有未绑定的方法。暂时忘记classmethods,看看这个:

>>> 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 中的事情要有趣得多,因为实际上未绑定的方法可以获取。您通常看不到 unbound classmethod,因为重点是它们在类创建时绑定到类,而不是在创建实例时未绑定然后绑定到每个实例。

但实际上,未绑定的方法只是任何为 Noneinstancemethod的方法。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 中的 2.x 版本,bound_baz.__func__new.instancemethod没有 3.x 等效版本。

文档说,为了 3.x 兼容性,new不推荐使用 ,types实际上,您可以在 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_classa是一种欺骗,尽管事实并非如此,但这似乎是让旧式和新式课程在所有通常的用例。classmethodclassobjFoo.__class__

于 2013-01-29T02:32:04.423 回答