2016-10-18 10 views
1

私はクラスDocumentを持っていますが、このクラスは実際にはインスタンス化するのが難しいので、作成するビルダーオブジェクトがあります。どちらの要素も私のものではないため、変更することはできませんビルダーでインスタンス化されたクラスから継承する方法は?

ここで、特定のメソッドを追加するだけで、Documentのサブクラスを作成します。提供ビルダーを使用して保つために、私はこれを試してみました:

class SpecialDocument(Document): 
    def __new__(cls, *args): 
     return DocumentBuilder(*args) 

    def __init__(self, *args, **kwargs): 
     #My initialization 

ここでの問題は__init__方法は__new__方法がでSpecialDocument(それはDocumentを返す)

を返さない原因実行したことがないということです私の特別なケース私はDocumentをどのように構築するかとは異なり、SpecialDocumentを構築する必要はありません。同じビルダーを使用する方法はありますか?そうでない場合は、どうすればいいですか?私はちょうどDocumentから継承して、特定の機能を追加したいのですが、メタクラスで実現できるかもしれませんが、私はそれらを使用したことはありません(おそらく私はそれを完全に理解していません)。問題

+0

本当に*サブクラス*が必要ですか?あなたは、あなたが望む行動だけを追加するために委任を使うことはできませんか? – Bakuriu

+0

'Document'と' DocumentBuilder'の関係は何ですか? –

+0

@PhilipTzou 'DocumentBuilder'は、パラメータなしで構築された場合に新しいDocumentオブジェクトを返す独立したクラスです(パラメータが存在する場合、パラメータは実際のドキュメントへのパスです) –

答えて

1

ここで実際にメタクラスは必要ありません。スーパークラスの__new__メソッドを適切に呼び出すだけです。あなたがそれをやっているやり方では、スーパークラスのインスタンス化はサブクラスから呼び出されていることを全く知らない。

class SpecialDocument(Document): 
    def __new__(cls, *args): 
     return super().__new__(cls, *args) 

    def __init__(self, *args, **kwargs): 
     #My initialization 

が、それはそれを行うには、通常の方法である - そしてあなたの「ビルダー」機能でコードが正しくDocmentの__new__内部に置かれた場合に動作します:

ので、ちょうどこの代わりのようなコードを書きますまたは__init__
コードではそれができないので、サブクラスをパラメータとしてビルダーに渡すことができます。実際の解決策は、通常のドキュメントを作成し、ビルドした後にクラスをスワップすることです。

def special_document_init(special_document): 
    ... 

class SpecialDocument(Document): 
    def my_special_method(self, ...): 
     ... 
    def overriden_method(self): 
     ... 
     result = super().overriden_method() 
     ... 

def build_special_document(*args): 
    document = DocumentBuilder(*args) 
    document.__class__ = SpecialDocument 
    special_document_init(document) 
    return document 
関連する問題