Python:获取未绑定的类方法

dar*_*ine 13 python python-3.x

你怎么能得到一个没有约束的类方法?

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

>>> Foo.bar
<bound method type.bar of <class '__main__.Foo'>>
Run Code Online (Sandbox Code Playgroud)

编辑:这是python 3.抱歉混乱.

aba*_*ert 19

Python 3没有未绑定的方法.classmethod暂时忘掉s,看看这个:

>>> class Foo:
...     def baz(self): pass
>>> Foo.baz
<function __main__.baz>
Run Code Online (Sandbox Code Playgroud)

在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>
Run Code Online (Sandbox Code Playgroud)

以同样的方式:

>>> class Foo:
...     @classmethod
...     def bar(cls): pass
>>> Foo.bar
<bound method type.bar of <class '__main__.Foo'>>
>>> Foo.bar.__func__
<function __main__.bar>
Run Code Online (Sandbox Code Playgroud)

事情在2.x中更有趣,因为实际上未绑定的方法.您通常无法看到未绑定classmethod,因为重点是它们在类创建时绑定到类,而不是保持未绑定状态,然后在实例创建时绑定到每个实例.

但实际上,一个不受约束的方法就是任何instancemethodim_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)
Run Code Online (Sandbox Code Playgroud)

请注意,这bound_baz.im_funcbound_baz.__func__3.x中的2.x版本,但new.instancemethod没有3.x等效版本.

文档说,new赞成使用types3.x兼容性,事实上,你可以在2.x中执行此操作:

unbound_baz = types.MethodType(bound_baz.im_func, None, bound_baz.im_class)
Run Code Online (Sandbox Code Playgroud)

但这在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)
Run Code Online (Sandbox Code Playgroud)

如果你打印出来,你会看到:

<unbound method type.bar>
Run Code Online (Sandbox Code Playgroud)

或者,使用您的示例,使用旧式类:

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

<unbound method classobj.bar>
Run Code Online (Sandbox Code Playgroud)

是的,也许这是一个有点欺骗了的im_classclassmethod一个旧式类是classobj即使这不是Foo.__class__,但它似乎是最合理的方式变老,款式新,样式类在所有的类似的工作通常的用例.