2012-09-16 5 views
14

と仮定以下のクラス:予想通りなぜ__getitem__はclassmethodにできませんか?

class Class(object): 
    @classmethod 
    def getitem(*args): 
     print 'getitem %s' % (args,) 
    @classmethod 
    def __getitem__(*args): 
     print '__getitem__ %s' % (args,) 

GetItemメソッドは動作します。それは、最初の引数としてClassを受信しますが、最初の引数としてtype__getitem__受け取る:

calling Class.getitem(test) 
getitem (<class '__main__.Class'>, 'test') 

calling obj.getitem(test) 
getitem (<class '__main__.Class'>, 'test') 

calling Class[test] 
'type' object has no attribute '__getitem__' 

calling obj[test] 
__getitem__ (<class '__main__.Class'>, 'test') 

__getitem__の背後にあっ魔法は何ですか?

答えて

18

特別な方法は、クラスではなく、インスタンスに見上げている - インスタンス上で検索され、通常の方法とは異なり、最初。 PythonデータモデルドキュメントのSpecial method lookupを参照してください。 getitem呼ばClass自身の属性でメソッド約Classtypeのインスタンスとして思考

、これはあなたが

Class.getitem(test) 

を行うときに、あなたがそれを教えて正確に何のためにそれは最初に見えることを意味します。しかし、あなたが

Class[test] 

使用する場合には、これをスキップし、(Class、またはそのメタクラスのクラスである)typeにまっすぐ行き、そうtype.__getitem__(Class, test)を呼び出します。だから、__getitem__は最初の引数としてtypeを取得します(具体的にはClass.__getitem__(test)のように、それでもClassを取得します)。この場合はPythonが検索する__getitem__が存在しません。存在させるには、クラスメソッドとしてClassに定義するのではなく、インスタンスメソッドとして定義するClassの独自のメタクラスを定義する必要があります。

+0

'クラスをインスタンスのインスタンスとして考える '。ありがとうございました。ありがとうございました。ありがとうございました。 – norbertpy

9

x[test]に電話すると、__getitem__属性のtype(x)が検査されます。 Class[test]の場合はのClassのメタクラスです。クラス全体を__getitem__にしたい場合は、それを新しいメタクラスの中に定義してください。 (それはあなたがメタクラスで行うものとして、魔法のようなものだ、言うまでもなく)

class Meta(type): 
    def __getitem__(self, arg): 
     print "__getitem__:", arg 


class X(object): 
    __metaclass__ = Meta 

X['hello'] # output: __getitem__ hello 
+0

問題の解決策はありますが、そのような構文糖をあまりにも多くコーディングしています。 実際のコードでは、メタクラス自体に__getitem__しようとしています:) – qMax

関連する問題