2017-01-18 16 views
0

スーパークラスの新しいインスタンス(a.k.a. "親"クラス)を作成するメソッドを持つクラスが必要です。そのクラスのインスタンスからクラスのインスタンスを作成するにはどうすればよいですか?

さらに、上記のクラスをサブクラス化し、このサブクラスでメソッドを継承し、そのメソッドを使用して独自のサブクラスのインスタンスをさらに作成できるようにします。

しかし、私はこのようにそれをやろう...

class Superclass: 
    def makeNew(self): 
     return self.__class__() #this isn't making a clean copy 

class Subclass(Superclass): 
    def __init__(self, value = [1]): 
     self.value = value 

    def setValue(self, newValue): 
     self.value[0] = newValue 

if __name__ == "__main__": 
    s = Subclass() 
    s.setValue(5) 
    other = s.makeNew() 
    print(s.value) 
    print(other.value) 

私は

>>> [5] #s.value 
>>> [5] #other.value 

はなぜself.__class__()は私に、スーパークラスのクリーンコピーを与えるものではありませんますか?

私は間違っていますか?私はどのようにしてクラスを作りたいですか?

+0

「クリーンコピー」とは何でしょうか?代わりに何を得ていますか?それにもかかわらず、新しいインスタンスを作成して返すサブクラスに '@ staticmethod'を定義する方法があります。 's'がサブクラスのインスタンスであれば' s.make_new_instance() 'で呼び出すことができます(これはstaticメソッドの名前です)。 – martineau

+0

「クリーンコピー」とは、元の「s」とは完全に別の意味です。 '[5] \ n [1]' –

答えて

4

これはあなたのmakeNewメソッドでは問題ありません。それはあなたの__init__の問題です。変更可能なデフォルト引数がある場合、その値を変更すると、将来のすべてのデフォルトが変更されます。あなたが代わりにやるべきことはこれです:

def __init__(self, value=None): 
    if value is None: 
     value = [1] 
    # ... 

その方法は、すべての新しいインスタンスではなく、同じリストにちょうどより多くの参照の新しいリストを作成しています。

補足として、それはvalueがリストであるようには見えません。もちろん、ここに表示されていない他のコードでも必要な場合がありますが、これがすべてのコードであれば、必要なものはすべてself.value = ...です。変更する代わりにself.valueを再割り当てするので、デフォルトの引数をうまく使うことができます。

+0

ニースキャッチ!リストと辞書は、ほとんどの場合デフォルトの引数については悪い考えです。 none解決策は私のfavですが、実際にはデフォルトの引数を持つ必要がない場合は、単純にそれを完全に残すことができます。 – Alan

+0

問題は 'makeNew'基底クラスメソッドで_is_です。 'self .__ class __()'を呼び出すとき、それは 'self'引数がサブクラスのインスタンスに設定されて呼び出された場合にサブクラスを参照しています(質問に示す' s.makeNew() 'の場合と同じです)。 – martineau

+0

@martineau:なぜそれが問題なのか分かりません。サブクラスで 'makeNew'を呼び出すと、スーパークラスのインスタンスが得られたので、それは問題ではなく、期待された振る舞いを呼び出すことはむしろ奇妙です。 – zondo

関連する問題