2

クラスの作成中に、派生クラスの基本クラスで定義されたクラス メソッドを自動的に実行したいと考えています。例えば:

class Base(object):
  @classmethod
  def runme():
    print "I am being run"

  def __metclass__(cls,parents,attributes):
    clsObj = type(cls,parents,attributes)
    clsObj.runme()
    return clsObj


class Derived(Base):
  pass:

ここで何が起こるかというと、Base が作成されると、''runme()'' が起動します。しかし、Derived が作成されても何も起こりません。

問題は、 Derivedの作成時に ''runme()'' も起動させるにはどうすればよいかということです。

これは私がこれまで考えてきたことです。DerivedメタクラスBaseに明示的に設定すると、機能します。しかし、私はそれが起こることを望んでいません。私は基本的に、明示的に設定しなくても、 DerivedがBaseのメタクラスを使用することを望んでいます。

4

4 に答える 4

2

この回答を参照してください。基本的に、 を呼び出すときtype(cls,parents,attributes)は、そのクラスのメタクラスに関する情報を渡さずにクラスを作成しています。したがって、返されるクラスには、必要なメタクラスがありません。代わりに metaclass がありますtype。(皮肉なことに、__metaclass__to do を定義することで、明示的にクラスにそのメタクラスを持たせないtype.__new__(meta, cls, parents, attrs)ことになります。) type を直接呼び出す代わりに、 meta がメタクラスである を呼び出す必要があります。

__metaclass__ただし、インラインで定義すると、これを実現できません。メソッド内から__metaclass__、そのメソッドを参照する方法はありません。これは、まだ定義されていないクラスのメソッドであるためです。あなたは次のようなことをしたい

def __metaclass__(cls, bases, attrs):
    type.__new__(metaclassGoesHere, cls, bases, attrs)

. . . metaclassGoesHereしかし、参照しようとしているのは、参照しようとしている内部のメソッドであるため、正しいことを行うために入れることができるものは何もありません。

したがって、メタクラスを外部で定義するだけです。

于 2012-06-21T03:40:19.393 に答える
0

クラスの作成時に何かをしたい場合は、 の__init__メソッドでそれを行う必要があり__metaclass__ます。

class foo(object):
    @classmethod
    def method(cls):
        print 'I am being run by', cls.__name__

    class __metaclass__(type):
        def __init__(self, *args, **kwargs):
            type.__init__(self, *args, **kwargs)
            self.method()

class bar(foo): pass

どちらが印刷されますか:

I am being run by foo
I am being run by bar
于 2013-11-15T19:50:19.000 に答える
0

これを試して、

class MyMetaclass(type): 

    def __new__(cls, name, bases, dct):

        runme()

        return super(MyMetaclass, cls).__new__(cls, name, bases, uppercase_attr)
于 2012-06-21T04:19:01.550 に答える
0

名前を変更し、メソッドをオーバーライドしないでくださいrunme()。インスタンス__init__(self)作成するたびに呼び出されます__init__()Derived

class Base(object):
    def __init__(self):
        print "I am being run"

class Derived(Base):
    pass

dummy_instance = Derived()

それをコピーして貼り付けると、印刷されますI am being run

于 2012-06-21T03:11:59.463 に答える