2017-11-16 7 views
3

を与える:すなわちは、これまでのところ、メタクラス矛盾まったく同じ方法で、SOの回答で他のすべての答えを

class M_A(type): pass 
class M_B(type): pass 
class A(metaclass=M_A): pass 
class B(metaclass=M_B): pass 

class M_C(M_A, M_B): pass 
class C:(A, B, metaclass=M_C): pass 
、あなたのメタクラスを構築し、それらのメタクラスの「参加」バージョンを継承します

しかし、私はこれらの人々があなた自身のメタクラスを構築しているところで、どのような世界に住んでいるのか分かりません!明らかに、他のライブラリのクラスを使用していて、メタプログラミングを完璧に扱わなければ、クラスのメタクラスをオーバーライドできるかどうかをどのように知っていますか? (明らかに私はまだそれらにハンドルを持っていない)。

私の問題は、次のとおりです。

私にエラー与えもちろんの
class InterfaceToTransactions(ABC): 
    def account(self): 
     return None 
    ... 

class Category(PolymorphicModel, InterfaceToTransactions): 
    def account(self): 
     return self.source_account 
    ... 

class Income(TimeStampedModel, InterfaceToTransactions): 
    def account(self): 
     return self.destination_account 
    ... 

「メタクラスの競合を:派生クラスのメタクラスは、そのすべての拠点のメタクラスの(非厳密)サブクラスでなければなりません" 私は上記のソリューションの多くのバリエーションを試してきましたが、次のことはうまくいかず、同じエラーが発生します。

class InterfaceToTransactionsIntermediaryMeta(type(PolymorphicModel), type(InterfaceToTransactions)): 
pass 

class Category(PolymorphicModel, InterfaceToTransactions): 
    __metaclass__ = InterfaceToTransactionsIntermediaryMeta 
    ... 

クラスメタ機能の中に何も入れていません。私はこのトピックに関するすべての他のSOの質問を読んだことがあります。単にそれを重複としてマークしないでください。

-------------------場合は、奇妙なことに-------

を解決策を受け入れた後1/8/18を編集私はこの新しい構成(私が受け入れたもの)でmakemigrationsを試行します、それはメタクラスのエラーを再度与えることを開始しますが、実行時にはまだ動作します。私がメタクラスを解読してマイグレーションすると、それはうまくいくでしょうが、毎回マイグレーションした後に戻しておかなければなりません。

+0

説明のために、 'Category'と' Income'の両方を 'InterfaceToTransactions'から継承する必要があるのは、' account'という抽象メソッドはどこですか?これだけであれば、Metaclassを使うのはちょっと残念です... –

+0

私はここで定義を短くしましたが、インターフェイスを利用するクラスのそれぞれに共通のかなり長いメソッドがあります。 – mastachimp

答えて

1

Python 3を使用している場合、派生したメタクラスを誤って使用しようとしています。

あなたは「同じエラー」を経験し、それ以外の可能性はない、より微妙なエラーではないので、これは起こっていることです。

class IntermediaryMeta(type(InterfaceToTransactions), type(PolymorphicModel)): 
    pass 

class Category(PolymorphicModel, InterfaceToTransactions, metaclass=IntermediaryMeta): 
    ... 

(少なくともABCMetaクラスはsuperを使用して共同作業することが保証されて、それが最初の拠点にクラッセにそれを置くのに十分な動機である) タプル)

だけに変更してみてください

これは新しいエラーと改善されたエラーをもたらす場合、これは、これらのクラスの一方または両方がいくつかの動機の1つのために実際に適切にコラボレーションできないことを意味します。それでは、ABCMetaに依存する継承ツリーを強制することは、他のすべてのものがPythonのような "大人に同意"するための言語ではほとんどその役割を果たしていないためです。

不幸にも、安全な「すべてを書き直す」からサルのパッチ適用まで、ブルートフォースのさまざまな方法を使用することです。「InterfaceToTransactions」は単に何もしないように定義されています。

あなたがそこに着く必要があり、何か助けが必要な場合、別の質問を投稿してください。

残念ながら、これは実際にメタクラスを使用する際の主な欠点です。

+0

これはTimeStampedModelを含めてうまくいきましたが、もちろん多態性の代わりにTSMを使って別に同じ構造のメタクラスを作成しなければなりませんでした。興味深いことに、重要なのはpy3互換、すなわちpy2スタイルの代わりに「metaclass = IntermediaryMeta」になっていたことだけでした。 – mastachimp

関連する問題