2011-06-28 111 views
-1

我是Python的新手,並且發現了一些我相信它的bug。Python - 爲什麼會發生這種情況?

編輯2011-09-30: 忘記它。現在我知道創建的屬性是靜態的並且在實例之間共享。 希望這個線程可以幫助另一個python新手處理和我一樣的情況。

考慮下面的代碼:

class test(): 

    dictionary1 = {} 
    list1 = [] 

    def method1(self): 
     self.dictionary1.update({'1': 'unique entry'}) 
     self.list1 = ['unique list entry'] 

t=test() 

print 'dictionary1 value:', t.dictionary1 
print 'list1 value:', t.list1 
t.method1() 
print 'dictionary1 new value:', t.dictionary1 
print 'list1 new value:', t.list1 

t2=test() 
print 'dictionary1 value:', t2.dictionary1, " -- error -- I just instantiated the class. The correct value would be {}" 
print 'list1 value:', t.list1 
t2.method1() 
print 'dictionary1 new value:', t.dictionary1 
print 'list1 new value:', t.list1 

現在的問題:

爲什麼在19行執行的代碼所示:{'1': 'unique entry'}。我相信這將是:{} 注意,該列表包含了正確的值:(在第20行空列表)[]

Using Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2 

對不起不是那麼好英語。來自巴西。

編輯2011-09-30: 忘記它。現在我知道創建的屬性是靜態的並且在實例之間共享。 希望這個線程可以幫助另一個python新手處理和我一樣的情況。

+24

規則no。 1:錯誤出現在您的代碼中或您對該功能的理解中,而不是在成熟的,經過充分測試的實現中。 – delnan

+2

您的代碼已完全損壞。發佈實際運行的內容。 – Daenyth

+0

'self.list1 = ['唯一列表項']的縮進是否正確?它看起來不在'method1'裏面。 – thegrinner

回答

14

test class的所有實例共享相同的字典和列表。初始化成員正確的方法是:直接在類體內分配

class Test(): 
    def __init__(self): 
     self.dictionary1 = {} 
     self.list1 = [] 

屬性將被計算一次,然後將所有實例之間共享。由於__init__方法每個實例運行一次,因此將爲每個實例創建一個新的列表和字典。

+3

他們分享它們是因爲OP聲明的是類變量(類似於其他語言中的靜態成員)。 – delnan

7

在班級主體中直接聲明的變量(static class variables)由班級的所有實例共享。因此,改變它們並不是一個好主意。

相反,初始化對象的成員變量在構造函數中:

class test(object): 
    def __init__(self): 
     self.dictionary1 = {} 
    def method1(self): 
     self.dictionary1.update({'1': 'unique entry'}) 
5

要添加到其他的答案,原因你看到不同的行爲爲dictlist是:當你寫self.dictionary1.update({'1': 'unique entry'}),你改變內容爲self.dictionary1,但它仍然是dict的對象。當您編寫self.list1 = ['unique list entry']時,需要使用新的list對象替換self.list1對象。您將通過執行以下操作獲得與dict相同的行爲:self.list1.append('unique list entry')

+0

'self.list1 = ...'沒有取代任何東西,因爲沒有東西可以替換,實例的__dict__'沒有關鍵字'list1',它只是添加它。碰巧,該班的 – SingleNegationElimination

+0

對不起;它將一個屬性添加到隱藏該類的屬性的實例中。 –

相關問題