12

これがPythonセッションです。

>>> class Z(type):
    def __new__(cls, name, bases, attrs):
        print cls
        print name
        return type(name, bases, attrs)
...     
>>> class Y(object):
    __metaclass__ = Z
...     
<class '__main__.Z'>
Y
>>> class X(Y):
...     pass
... 
>>> class W(Y):
...     __metaclass__ = Z
...     
<class '__main__.Z'>
W
>>> 

クラスXIを定義した後、Z._new __が呼び出され、発生していない2行を出力することを期待します(メタクラスは継承されますか?)

4

1 に答える 1

14

問題は、cls呼び出し時に引数(メタクラスオブジェクト)が渡されないことですtype。したがって、作成されて返されるクラスオブジェクトYには、メタクラスへの参照がありませんZ

__new__の最後の行をに置き換える場合

return super(Z, cls).__new__(cls, name, bases, attrs)

その後、それは動作します。clsで使用されている場合でも、ここではバインドされていないメソッドが返されるため、引数としても指定superする必要があることに注意してください(詳細については、ここを参照してください)。clssuper

スーパーを使用する代わりに、次のものを使用できます。

 return type.__new__(cls, name, bases, attrs)

重要なことは、classmethodにcls(メタクラスオブジェクト)を与えることです。短い形式はそれ自体で引数を埋めますが、これはもちろん間違っています。このエラーは、間違った引数を使用してインスタンスメソッドを呼び出すのと似ています。Z__new__type(name, bases, attrs)typeclsself

superこれはより良いスタイルなので、私はを使用することを好みます。

于 2009-11-20T14:35:24.837 に答える