【问题标题】:Accessing a List inside a class as part of a dictionary in Python在 Python 中作为字典的一部分访问类中的列表
【发布时间】:2014-01-06 21:11:55
【问题描述】:

我在 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   
]

提前感谢您的帮助

【问题讨论】:

  • 请修正缩进
  • 我只想指出,将变量放在__init__ 函数之外时,这与C++ 中的静态变量相同。类的所有实例对于这些变量将具有相同的值

标签: python arrays list object dictionary


【解决方案1】:

是的,您的列表实例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 = ":("

【讨论】:

    【解决方案2】:

    您似乎对在 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'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      • 2017-08-12
      相关资源
      最近更新 更多