2011-08-15 69 views
2

我寫了下面的代碼:意外的結果在Python類初始化

class node: 
    def __init__(self, title, series, parent): 
     self.series = series 
     self.title = title 
     self.checklist = [] 
     if(parent != None): 
      self.checklist = parent.checklist 
     self.checklist.append(self) 

當我創建的對象是這樣的:

a = node("", s, None) 
b = node("", s, a) 
print a.checklist 

出乎意料的是,它顯示了A和B的對象作爲print語句的輸出。 我是python的新手。所以,可能有一些愚蠢的錯誤。

謝謝。

+1

'self.checklist = parent.checklist'如果parent = None應該引發AttributeError,我認爲它應該在if語句中。而且,使用'parent不是'而不是'!=',並且不要在if語句(帶有一個條件)時使用parantheses。 – utdemir

+0

對不起。這是一個複製錯誤。糾正。 – mihsathe

回答

6

你做self.checklist = parent.checklist這意味着兩個實例共享相同的列表。他們都自己添加它,所以當你打印它時,你會看到兩個實例。

也許你想製作父列表的副本? self.checklist = parent.checklist[:]

+0

是的。那做了這個工作。非常感謝。不知道這種類似靜態的行爲。 – mihsathe

1

小心切片標誌的[:] 這將使列表的副本,但是如果列表包含其他列表,這些列表本身將通過參考,不作爲新的對象被複制。

例如::

>>> a = [1,2,3] 
>>> b = [4,5,6] 
>>> x = [a,b] 
>>> y = x[:] 
>>> x 
[[1, 2, 3], [4, 5, 6]] 
>>> y 
[[1, 2, 3], [4, 5, 6]] 
>>> a.append(66) 
>>> x 
[[1, 2, 3, 66], [4, 5, 6]] 
>>> y 
[[1, 2, 3, 66], [4, 5, 6]] 

    ^^^^^^^^^ unexpectedly y has an updated a inside it, even though we copied it off. 


>>> import copy 
>>> y = copy.deepcopy(x) 
>>> a.append(77) 
>>> x 
[[1, 2, 3, 44, 55, 66, 77], [4, 5, 6]] 
>>> y 
[[1, 2, 3, 44, 55, 66], [4, 5, 6]] 

        ^^^^^ y is a seperate object and so are all its children 

您可能會感興趣的使用ID(Y)看對象y的內存地址。

+0

那麼我們甚至可以拷貝那些東西? – mihsathe

+0

我不確定你的意思。如果要製作一個未連接的對象副本並且不能100%確信它沒有子對象,請使用copy.deepcopy。一般在每次你想要一個不相關的副本時使用deepcopy。但總的來說,複製可變對象往往是一種標誌,你可以通過其他方式簡化它 –