python更新类';当变量在其他地方发生变化时,使用列表或字典

python更新类';当变量在其他地方发生变化时,使用列表或字典,python,arrays,oop,object,dictionary,Python,Arrays,Oop,Object,Dictionary,在外部更改后,如何更新包含其他self.variable的self.dictionary或self.list 例如,我们有以下测试类: class Test(): def __init__(self): self.some_number = 0 self.other_number = 0 self.lst=[self.some_number, self.other_number] self.dic={'some_number': se

在外部更改后,如何更新包含其他self.variable的self.dictionary或self.list

例如,我们有以下测试类:

class Test():
   def __init__(self):
       self.some_number = 0
       self.other_number = 0
       self.lst=[self.some_number, self.other_number]
       self.dic={'some_number': self.some_number, 'other_number': self.other_number}

   def update_values(self):
       self.number = 2
       self.other_number = 3
然后更新值:

test = Test()                  

print(test.dic)
print(test.lst)

test.update_values()

print(test.dic) 
print(test.lst)
结果无变化:

{'other_number': 0, 'some_number': 0}
[0, 0]
{'other_number': 0, 'some_number': 0}
[0, 0]

我实际上认为,字典和列表中包含了指向内存中某个地方的变量的引用。因此,如果这些改变,也应该改变。但事实似乎并非如此。有什么解释吗?

是的,名字是参考资料。但是当在
update_values
中执行
self.number=which
操作时,您正在重新绑定self.number以指向另一个整数
self.lst
仍然包含对原始整数的引用

如果整数是可变的,您可以对
self.number
的值进行变异,这将反映在
self.lst
中。但他们不是,所以你不能。如果您使用了其他类型的对象,那么它将是可见的。例如:

def __init__(self):
    self.first = [0]
    self.lst = [self.first]

def update_values(self):
    self.first[0] += 1

这里我们先对self.lst进行变异,而不是重新绑定它,因此self.lst将反映更改。

是的,名称是引用。但是当在
update_values
中执行
self.number=which
操作时,您正在重新绑定self.number以指向另一个整数
self.lst
仍然包含对原始整数的引用

如果整数是可变的,您可以对
self.number
的值进行变异,这将反映在
self.lst
中。但他们不是,所以你不能。如果您使用了其他类型的对象,那么它将是可见的。例如:

def __init__(self):
    self.first = [0]
    self.lst = [self.first]

def update_values(self):
    self.first[0] += 1

这里我们先对self.lst进行变异,而不是重新绑定它,因此self.lst将反映更改。

整数是不可变的,所以这不起作用。但您可以使用列表实现您想要的:

class Test(object):
   def __init__(self):
       self.some_number = [0]
       self.other_number = [0]
       self.lst=[self.some_number, self.other_number]
       self.dic={'some_number': self.some_number, 
           'other_number': self.other_number}

   def update_values(self):
       self.some_number[0] = 2
       self.other_number[0] = 3


test = Test()

print(test.dic)
print(test.lst)

test.update_values()

print(test.dic) 
print(test.lst)       
输出

{'some_number': [0], 'other_number': [0]}
[[0], [0]]
{'some_number': [2], 'other_number': [3]}
[[2], [3]]
请注意,我们必须对
一些
其他
列表进行变异,即修改其内容。如果我们只是用新列表替换它们,那么我们就无法获得所需的传播:

#This doesn't do what we want because it replaces the old list
#objects with new ones.
def update_values(self):
    self.some_number = [2]
    self.other_number = [3]

Python名称绑定的工作方式一开始可能有点令人困惑,特别是如果您来自另一种语言。在我看来,最好用它自己的术语来理解这个习语,而不是用引用、指针等来理解它

我建议你看一看,由这么老的内德·巴奇尔老人;这篇文章也可以在YouTube上以视频形式获得


你在评论中问:


如果python动态地重建列表/dic,那么旧的 数据?Python会从一个内存复制到另一个内存吗?还是重新分配

Python变量,无论是简单变量还是像self.some\u number这样的属性,都不是一个保存值的容器。它是一个绑定到对象的名称
a=0
创建一个值为0的
int
对象,并将该对象绑定到本地范围中的名称
a
。如果随后执行
a=2
,将创建一个值为2的
int
对象,并将其绑定到
a
,并回收以前的0对象

(为了提高效率,缓存-5和256(包括-5和256)范围内的小整数,在需要时创建该范围外的整数对象,在不再需要时销毁它们,即不再有任何名称绑定到它们时)

当你这样做的时候

a = 1234
b = 5678
mylist = [a, b]
创建两个整数对象并将其绑定到名称
a
b
。下面,
a
1234
对象的名称,
b
5678
对象的名称。有时可以这样描述:
a
保存对
1234
整数对象的引用。但在我看来,将
a
视为字典中的一个键,并将
1234
integer对象视为关联值更好(更简单)

然后
mylist=[a,b]
mylist[0]
作为
1234
对象的备用名称,将
mylist[1]
作为
5678
对象的备用名称。
1234
5678
对象本身不会复制到内存中。本质上,Python列表是指向它所持有的对象的指针数组(添加了一些机制,使列表成为一个合适的Python对象)

在mkrieger1的代码中,每次检索
Test.lst
属性时都会创建一个新的列表对象;没有“旧列表”,除非您通过某种方式将其绑定到某个地方来保存它


我希望这是有帮助的,不要太混乱。:)

整数是不可变的,所以这不起作用。但您可以使用列表实现您想要的:

class Test(object):
   def __init__(self):
       self.some_number = [0]
       self.other_number = [0]
       self.lst=[self.some_number, self.other_number]
       self.dic={'some_number': self.some_number, 
           'other_number': self.other_number}

   def update_values(self):
       self.some_number[0] = 2
       self.other_number[0] = 3


test = Test()

print(test.dic)
print(test.lst)

test.update_values()

print(test.dic) 
print(test.lst)       
输出

{'some_number': [0], 'other_number': [0]}
[[0], [0]]
{'some_number': [2], 'other_number': [3]}
[[2], [3]]
请注意,我们必须对
一些
其他
列表进行变异,即修改其内容。如果我们只是用新列表替换它们,那么我们就无法获得所需的传播:

#This doesn't do what we want because it replaces the old list
#objects with new ones.
def update_values(self):
    self.some_number = [2]
    self.other_number = [3]

Python名称绑定的工作方式一开始可能有点令人困惑,特别是如果您来自另一种语言。在我看来,最好用它自己的术语来理解这个习语,而不是用引用、指针等来理解它

我建议你看一看,由这么老的内德·巴奇尔老人;这篇文章也可以在YouTube上以视频形式获得


你在评论中问:


如果python动态地重建列表/dic,那么旧的 数据?Python会从一个内存复制到另一个内存吗?还是重新分配

Python变量,无论是简单变量还是像self.some\u number这样的属性,都不是一个保存值的容器。它是一个绑定到对象的名称
a=0
创建一个值为0的
int
对象,并将该对象绑定到本地范围中的名称
a
。如果执行
a=2
操作,将创建一个值为2的
int
对象并将其绑定到<