2011-01-24 9 views
1

私は、リファレンスがPythonでどのように動作するかを理解していることに間違いがあると考えている状況に遭遇しました。Pythonリファレンス

たちは二つのクラスがあるとします。

class A: 
    def __init__(self): 
     self.x = [1,2,3] 

    def modify(self): 
     self.x.append(4) 

    def reset(self): 
     self.x = [] 

class B: 
    def __init__(self, x): 
     self._x = x 

    def say(self): 
     print self._x 




a = A() 
b = B(a.x) 

b.say() 
a.modify() 
b.say() 
a.reset() 
b.say() 

私が期待される出力をした:

[1, 2, 3] 
[1, 2, 3, 4] 
[] 

私が得た出力ました:

[1, 2, 3] 
[1, 2, 3, 4] 
[1, 2, 3, 4] 

に思えるその私が呼ばれたときreset()を設定し、self.xを新しいリストに設定すると、参照番号B独立して生き残り、参照の代わりにコピーになった。これは正しい理解ですか?

答えて

10

reset()方法

def reset(self): 
    self.x = [] 

self.xに格納されているオブジェクトを変更しない - それはむしろその後self.xに格納されている新しい空のリストを作成します。古いリストは変更されていません(まだそれはb._xによって参照されているため、ガベージコレクションされません)。新しい動作を作成する代わりに、既存のリストを空にするには、後で実行する動作を取得するには、既存のリストを空にすることをお勧めします。

+0

もう1つの方法は、@propertyデコレータを使用してxにアクセスすることです。 – VGE

3

a.xを[]に割り当てるときには、新しい空の配列を参照の間にa.xに代入するのではなく、b._xをそのまま維持します。変更と代わりに配列にしたい場合は、あなたのケースで、それがすべての内容は、これを行うのdelete:

del a.x[:] 
0

実際には、それは別のリストになったという点でコピーが、xとなったBに_xされていません。

関連する問題