2016-04-06 11 views
1

は、この例を考えてみましょう:メタクラスメソッドをメソッド解決に参加させることは可能ですか?

class Meta(type): 
    def method(*_, **__): 
     print('Meta') 


class A(object): 
    __metaclass__ = Meta 


class B(object): 
    @classmethod 
    def method(*_, **__): 
     print('B') 


class C(A, B): 
    pass 


C.method() # prints 'B' 

ここではそれMetaメタクラスだで定義されている、方法methodを持つクラスAを、持っています。クラスBもありますが、メソッドmethodもありますが、クラスメソッドとして定義されています。その結果、AB両方から継承

クラスCは、クラスBからmethodを有しています。

しかしAmethodクラスメソッドとして定義されていた場合、CAからmethodを継承していました。

Meta.methodは、このメタクラスを使用するクラスのクラスメソッドであるかのように継承に参加できるようにしたいと考えています。どういうわけか可能ですか?

+0

'C'はメタクラスとして' Meta'を持ち、 'A'のサブクラスもそうです。 'A'を振るのと同じように、' C'は 'method'という独自の定義を持っているように振舞うべきでしょうか? – user2357112

答えて

1

タイプのメソッドは、オブジェクト自体の属性をルックアップすると失敗します。これをインスタンス属性対クラス属性と比較してください。これはまったく同じです。

MROに参加する方法が必要な場合は、それをクラスそのものに置きます。

class Meta(type): 
    def __new__(mcls, name, bases, body): 
     cls = super(Meta, mcls).__new__(mcls, name, bases, body) 
     if not hasattr(cls, 'method'): 
      @classmethod 
      def method(*_, **__): 
       print('Meta') 
      cls.method = method 
     return cls 

これは、まだこのようなメソッドがない場合にのみ、新しく作成されたクラスにメソッドをスティックします。これにより、クラス(または任意のサブクラス)がメタクラス提供のメソッドをオーバーライドできるようになり、サブクラスが継承される可能性のあるサブクラスと同じものを取得できなくなります。

関連する問題