Python 访问字段:如果存储在dict中,则为不同的值
我的问题看起来像这样Python 访问字段:如果存储在dict中,则为不同的值,python,dictionary,scope,Python,Dictionary,Scope,我的问题看起来像这样 # Module.py class TestClass: name = "default" nameDict = {'name':"standard"} def __init__(self, name): self.name = name self.nameDict['name'] = name 然后我从另一个模块调用字段。该类在之前启动,我调用name字段,如下所示: Module.TestClass("newNam
# Module.py
class TestClass:
name = "default"
nameDict = {'name':"standard"}
def __init__(self, name):
self.name = name
self.nameDict['name'] = name
然后我从另一个模块调用字段。该类在之前启动,我调用name字段,如下所示:
Module.TestClass("newName")
# Inside another function
print(Module.TestClass.name)
print(Module.TestClass.nameDict['name'])
其中:
default #name
newName #nameDict
我不明白为什么会有不同的价值观。有人知道为什么会这样吗
谢谢您的时间。这种行为也让我感到惊讶:
import Module
# Inside another function
print(Module.TestClass.name) #<-- default
print(Module.TestClass.nameDict['name']) #<-- standard
foo = Module.TestClass("newName")
print(Module.TestClass.name) #<-- default
print(Module.TestClass.nameDict['name']) #<-- newName
你所看到的差异是因为——
>>> class CA:
... d = [1,2]
...
>>> CA.d
[1, 2]
>>> c = CA()
>>> c.d
[1, 2]
>>> id(c.d) == id(CA.d)
True
>>> c.d.append(3)
>>> CA.d
[1, 2, 3]
>>> c.d = [1,2,3,4,5]
>>> CA.d
[1, 2, 3]
>>> CA.d = [1,2,3,4,5,6]
>>> CA.d
[1, 2, 3, 4, 5, 6]
>>> d = CA()
>>> d.d
[1, 2, 3, 4, 5, 6]
>>> c.d
[1, 2, 3, 4, 5]
这是一个有趣的问题;发生了很多事情
Module.TestClass
是您在“Module.py”中定义的类。使用Module.TestClass(“newName”)
,您正在创建该类的实例,但没有保存它
当您打印(Module.TestClass.name)时,您正在打印Module.TestClass
的name
属性的值,该属性是类,不是该类的实例。您之前给出实例的name
不会更改类的“name
属性
真正有趣的是打印(Module.TestClass.nameDict['name'])
。即使您仍在访问类的nameDict
属性,它也会受到您先前创建的实例的影响。这是因为Python变量包含对对象的引用。定义类时,为类范围中的属性nameDict
分配了一个字典。类和类的所有实例都指向了完全相同的dictionary对象。所以,如果你在一个地方改变它,它在任何地方都会改变,因为它实际上是完全相同的格言
下面是一个很好的方法来完成您想要完成的事情:
# Module.py
class TestClass(object):
def __init__(self, name='default'):
self.name = name
self.nameDict = {'name': name}
# other.py
testclass_instance = Module.TestClass("newName")
# Inside another function
print(testclass_instance.name) # newName
print(testclass_instance.nameDict['name']) # newName
这是因为
TestClass.name
是一个字符串对象,因此是不可变的,而TestClass.nameDict
是一个可变的字典对象。因此,当您执行self.name=name
操作时,将在实例上创建一个具有“newName”值的新name变量,而当您执行self.nameDict['name']=name
操作时,dict类变量将发生变异
要验证此行为,可以检查变量的id:
例如:-
class TestClass(object):
...
def __init__(self, newName):
print(id(self.name)) #1
self.name = newName
print(id(self.name)) #2
print(id(self.nameDict)) #3
self.nameDict['name'] = newName
print(id(self.nameDict)) #4
1将不同于2,而3和4将相同。
进一步参考:-类和实例都共享相同的dict。这就是为什么仅仅创建一个实例就会更改类的dict;它们实际上是同一个物体。谢谢你的解释。Python提供了一大堆这样的陷阱。对我来说,这更像是一种爱恨。谢谢你的回答!我想我应该用一个实例来调用它,但我试图不这样做,因为我是如何编写代码的。我会重写它!很高兴我能帮忙:)。在这种情况下,您是否可以接受,以便将问题标记为已回答?不知道如何将类变量复制到实例。这对我来说是关键的缺失点。非常感谢。
class TestClass(object):
...
def __init__(self, newName):
print(id(self.name)) #1
self.name = newName
print(id(self.name)) #2
print(id(self.nameDict)) #3
self.nameDict['name'] = newName
print(id(self.nameDict)) #4