2016-07-30 5 views
0

は、私は次のクラスがあるとします。インスタンスをサブクラスに「昇格」する方法は?

class Plain(object): 
    def speak(self): 
     print 'ho-hum' 

class Fancy(Plain): 
    def exult(self): 
     print 'huzzah!' 

plain = Plain() 
plain.speak() 
# ho-hum 
plain.exult() 
# --------------------------------------------------------------------------- 
# AttributeError       Traceback (most recent call last) 
# <ipython-input-585-5f782c9ea88b> in <module>() 
# ----> 1 plain.exult() 
fancy = Fancy() 
fancy.speak() 
# ho-hum 
fancy.exult() 
# huzzah! 

を...といくつかの理由で、私はそれがFancyのインスタンスになるようPlainのインスタンスを「促進」にしたい、とします。

私は、私は常に、インスタンスの__class__属性を変更することができます知っている:

plain.__class__ = Fancy 
plain.exult() 
# huzzah! 

...しかし、私はこれを行うには良いことではないことを、様々なSOポスト(例えば、ここ、ここ)(から集まります少なくとも生産コードではない)。

インスタンスをサブクラスに昇格させるための「生産コードにふさわしい」方法がありますか?


FWIW、この問題に私をもたらし、現実世界のユースケースは以下の通りです。私は、Webサービスのクライアントを実装するサードパーティライブラリを使って作業しています。このクライアントができることの中には、さまざまなクラスのインスタンスが返されます。これらのクラスは非常に少数のメソッドを提供し、それらのメソッドは非常に弱いです。私はこれらのクラスのサブクラスをもっと強力なメソッドで簡単に書くことができますが、それらを有効にするために、APIの元のクラスのインスタンスを現在返すAPI関数のラッパーも記述する必要があります。常に、このラッパーは元の( "wrappee")関数によって返されたインスタンスを、拡張されたサブクラスのインスタンスに昇格させるだけで済みます。あなたはもちろん

fancy = Fancy(plain) 

を使用し、平野のインスタンスが引数として与えられた場合にどうするか、ファンシーのコンストラクタで定義することができ

+1

可能な重複http://stackoverflow.com/questions/10030412/how-to-convert-inherit -parent-to-child-class) – kwarunek

+1

あなたがしたいのは、["状態"のデザインパターン](https://en.wikipedia.org/wiki/State_pattern)です。適切なクラスのインスタンスを作成するためのコンテナオブジェクトが必要です。低レベルのビットを軽く叩いてハックしようとしないでください。 –

答えて

3

class Plain: 
    def __init__(self, foo, bar): 
     self.foo = foo 
     self.bar = bar 
     self.status = 'plain' 

class Fancy: 
    def __init__(self, something): 
     if isinstance(something, Plain): 
       self.foo = something.foo 
       self.bar = something.bar 
     self.status = 'fancy' 
[?子クラスに変換する方法(継承)親](の
+0

OPの使用例では、サブクラス(is-a)ではなくラッパー(has-a)を使用します。しかしどちらにしても、すでに言ったように、あなたはファンシーの__init__を使うでしょう。 –

関連する問題