2014-01-06 32 views
0

我在Python中遇到了一個奇怪的問題。如果是C++,我會在內存分配錯誤的東西線,可能導致此在Python中作爲字典的一部分訪問類中的列表

我有對象的字典思想。每個對象都有一個已經初始化的列表。

一旦字典已經被創建和初始化的對象,我嘗試訪問屬於在字典中的項目之一的名單。出於某種奇怪的原因,我似乎無意中使用了相同的列表來創建字典中的第二個和第三個對象,導致爲其他對象也打印相同的列表。

如果可能的話,有人可以幫我嗎?

這裏是我的代碼:

import random 

class ClassOne(): 
name = "" 
arrayToPrint = [] 

def __init__(self): 
    print("initialized class object") 
    name = "" 
    arrayToPrint = [] 

class ClassTwo: 
    nameTwo ="" 


x= {} 
#Initializing the dictionary 
for i in range(3): #Creating a dictionary with 3 items in it 
classOne= ClassOne() 
classOne.name = str(i) 
#wanted to create each of the lists with random lengths 
numberOfarraysToAdd =random.randint(1,9) 
print ("number of arrayToPrint for class %d = %d" % (i, numberOfarraysToAdd)) 
for j in range(numberOfarraysToAdd): 
    #Initializing the list within the dictionary 
    classTwo = ClassTwo() 
    classTwo.nameTwo = random.randint(1,20) 
    classOne.arrayToPrint.append(classTwo) 
x[i] = classOne #Copying the object of classOne into the dictionary with key as i 
classOne = None 

#Getting the code to print the dictionary and list 
for i in x: #traversing the dictionary 
print ("class name = %s" % x[i].name) 
print ("arrayToPrint = [") 
for j in range(len(x[i].arrayToPrint)-1): #traversing the list within the dictionary item 
    print ("f(%d) = %s\t" % (j, x[i].arrayToPrint[j].nameTwo)) 
print ("]") 

這裏是我得到的輸出。如果你觀察f(0)到f(21)對所有類都是一樣的。這告訴我,Python在字典中的所有項目中使用相同的列表,還是我做錯了什麼?

initialized class object 
number of arrayToPrint for class 0 = 9 
initialized class object 
number of arrayToPrint for class 1 = 7 
initialized class object 
number of arrayToPrint for class 2 = 7 
class name = 0 
arrayToPrint = [ 
f(0) = 17 
f(1) = 14 
f(2) = 10 
f(3) = 4  
f(4) = 19 
f(5) = 9  
f(6) = 9  
f(7) = 13 
f(8) = 11 
f(9) = 14 
f(10) = 19 
f(11) = 7 
f(12) = 6 
f(13) = 13 
f(14) = 1 
f(15) = 16 
f(16) = 1 
f(17) = 4 
f(18) = 6 
f(19) = 15 
f(20) = 6 
f(21) = 4 
] 
class name = 1 
arrayToPrint = [ 
f(0) = 17 
f(1) = 14 
f(2) = 10 
f(3) = 4  
f(4) = 19 
f(5) = 9  
f(6) = 9  
f(7) = 13 
f(8) = 11 
f(9) = 14 
f(10) = 19 
f(11) = 7 
f(12) = 6 
f(13) = 13 
f(14) = 1 
f(15) = 16 
f(16) = 1 
f(17) = 4 
f(18) = 6 
f(19) = 15 
f(20) = 6 
f(21) = 4 
] 
class name = 2 
arrayToPrint = [ 
f(0) = 17 
f(1) = 14 
f(2) = 10 
f(3) = 4  
f(4) = 19 
f(5) = 9  
f(6) = 9  
f(7) = 13 
f(8) = 11 
f(9) = 14 
f(10) = 19 
f(11) = 7 
f(12) = 6 
f(13) = 13 
f(14) = 1 
f(15) = 16 
f(16) = 1 
f(17) = 4 
f(18) = 6 
f(19) = 15 
f(20) = 6 
f(21) = 4 
] 

預先感謝任何幫助

+2

請解決您的壓痕 – MattDMo

+2

我只想把變量時,外面的''__init__函數,同樣的事情在C++中的靜態變量指出。該類的所有實例對於這些變量都具有相同的值 – IanAuld

回答

3

是的,你的清單arrayToPrint的實例是類變量,因此共享。用此來解決這個問題:

class ClassOne(): 
    def __init__(self): 
     print("initialized class object") 
     self.name = "" 
     self.arrayToPrint = [] 

在這旁邊,你__init__函數的最後兩行沒有做任何事情 - 他們創造局部變量,只是偶然有一個共同的名字與類變量,而消失之後。所以,備案,你這是怎麼正確地訪問類變量:

class X: 
    classVariable = 0 

    def __init__(self): 
     X.classVariable += 1 
     self.anotherExampleOfAnInstanceVariable = 0 

     aLocalVariableNoOneWillEverKnowAbout = ":(" 
0

它看起來像您有在課堂上是如何在C++和Python宣佈與差異的問題:

要使用分配價值類與init方法,你必須將屬性:

def __init__(self, name, array_to_print): # note Python uses lists/dictionaries not arrays and you should use underscores instead of pascalCase 
    self.name = name 
    self.array_to_print = array_to_print 

任何事情__init__方法外聲明將在同一類的所有實例之間共享。

class Foo: 
    name = 'Ian' 

    def __init__(self): 
     blah blah 

Foo類的每個實例都將有一個屬性,叫做name,它會被設置爲'Ian'所有實例。