18

バインドされていないクラスメソッドを取得するにはどうすればよいですか?

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

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

編集:これはPython3です。混乱してすみません。

4

1 に答える 1

24

Python3にはバインドされていないメソッドはありません。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。これは、インスタンスの作成時にバインドされていない状態で各インスタンスにバインドされるのではなく、クラスの作成時にクラスにバインドされるためです。

しかし、実際には、バインドされていないメソッドは、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)

これは3.xbound_baz.im_funcの2.xバージョンですが、3.xに相当するものはありません。bound_baz.__func__new.instancemethod

ドキュメントには、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です。newそして個人的には、明示的に2.xのみで、3.xに移植できないことをしているときは、使用する方が明確だと思います。

とにかく、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そうではありませんが、それはちょっとしたごまかしかもしれませんが、古いスタイルと新しいスタイルのクラスをすべてのクラスで同様に機能させるための最も合理的な方法のようです通常のユースケース。classmethodclassobjFoo.__class__

于 2013-01-29T02:32:04.423 に答える