2017-06-19 20 views
4

この質問に重複がある場合は、申し訳ありませんが、私はそれを見つけられませんでした。__getattribute__によって返されたPython呼び出しメソッド

私はこの単純なPythonのクラスを持っている:

class NothingSpecial: 
    @classmethod 
    def meth(cls): 
      print("hi!") 

そして私はさまざまな方法でメソッドを取得しようとしている:

a = (object.__getattribute__(NothingSpecial, 'meth')) 

b = (getattr(NothingSpecial, 'meth')) 

私がしなければ質問は、次のとおりです。

b() 

$hi!

はリターンですが、私はやるとき:

a() 

TypeError: 'classmethod' object is not callable

どのように私はaメソッドを実行することができますか?

+1

どうしてあなたは 'object .__ getattribute__'を使用していますか?それは間違った '__getattribute__'です。 – user2357112

+0

@ user2357112私はそれがどのように動作するか完全に理解しようとしているので、私はそれを使用しています –

答えて

5

descriptor protocolをバイパスしていて、バインドされていないクラスメソッドがあります。

ソリューションは__get__ method存在がある場合は、プロトコルを起動することです、また

>>> a.__get__(None, NothingSpecial) 
<bound method NothingSpecial.meth of <class '__main__.NothingSpecial'>> 
>>> a.__get__(None, NothingSpecial)() 
hi! 

使用:

if hasattr(a, '__get__'): 
    a = a.__get__(None, NothingSpecial) 
a() 

は今クラスメソッドは、クラスにバインドされ、それが再び動作します正しい__getattribute__、実際にクラス属性に記述子プロトコルを適用する方法を知っているもの。クラスはobject.__getattribute__が、type.__getattribute__を使用しないでください:あなたは実際にメタクラスがここ__getattribute__の実装をオーバーライドできるようにtype(NothingSpecial).__getattribute__にアクセスしたいと思います

>>> type.__getattribute__(NothingSpecial, 'meth') 
<bound method NothingSpecial.meth of <class '__main__.NothingSpecial'>> 

+0

なぜ最初のパラメータがNoneですか?私は試してみましたが、うまくいきましたが、すべてが少し新しくなりました。質問が基本的なものであればごめんなさい –

+0

なぜなら、 'isinstance(NothingSpecial、type)は' NothingSpecial .__ getattribute__'を 'object'から継承しています。 ) '? –

+0

@DamianLattenero:最初の引数は*インスタンス*のものですが、インスタンスではなくクラスがあります。 –

関連する問題