在Python中访问类中的List作为字典的一部分

时间:2014-01-06 21:11:56

标签: python arrays list object dictionary

我在Python中遇到了一个奇怪的问题。如果它是C ++,我会想到可能导致这个

的内存分配错误

我有一个对象字典。每个对象都有一个已初始化的列表。

一旦创建了字典并初始化了对象,我就会尝试访问属于字典中某个项目的列表。由于一些奇怪的原因,我似乎无意中使用了相同的列表来创建字典中的第二个和第三个对象,从而导致为其他对象打印相同的列表。

有人可以帮我解决一下吗?

这是我的代码:

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 个答案:

答案 0 :(得分: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 = ":("

答案 1 :(得分: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'