17

次のクラスを想定します。

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

getitem メソッドは期待どおりに動作します。Class最初の引数として__getitem__受け取りますがtype、最初の引数として受け取ります。

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__ですか?

4

2 に答える 2

26

特別なメソッドは、最初にインスタンスで検索される通常のメソッドとは異なり、インスタンスではなくクラスで検索されます。Python データ モデル ドキュメントの特殊なメソッド ルックアップを参照してください。

Classのインスタンスとして考えるとtype、これはあなたがするときを意味します

Class.getitem(test)

それは最初にあなたが伝えたことを正確に探します:Classと呼ばれる 自身の属性のメソッドgetitemです。でも、使うときは

Class[test]

これをスキップして、type( のクラスClassまたはそのメタクラスである) に直接進み、 を呼び出しますtype.__getitem__(Class, test)。つまり、最初の引数として get が取得されるのではなく (明示的に が取得__getitem__された場合と同様に取得されます)、この場合 Python が探す が存在しないということです。それを存在させるには、クラスメソッドとして定義するのではなく、インスタンスメソッドとして定義する独自のメタクラスを定義する必要があります。typeClassClass.__getitem__(test)__getitem__ClassClass

于 2012-09-16T13:03:45.867 に答える
16

を呼び出すx[test]と、インタープリターtype(x)は属性を検査し__getitem__ます。のメタクラスClass[test]の場合、つまり. クラス全体の が必要な場合は、新しいメタクラス内で定義します。(言うまでもなく、これはメタクラスで行うことと同様、一種の魔法です)Classtype__getitem__

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


class X(object):
    __metaclass__ = Meta

X['hello'] # output: __getitem__ hello
于 2012-09-16T13:02:48.393 に答える