如何解决为什么在 __exit__ 函数中不改变参考工作?
import copy
class Atomic:
def __init__(self,mutable,Shallow_copy = True):
self.original = mutable
self.copy = copy.copy if Shallow_copy else copy.deepcopy
def __enter__(self):
self.modified = self.copy(self.original)
return self.modified
def __exit__(self,exc_type,exc_value,exc_tb):
if exc_type is None:
self.original[:] = self.modified
所以我在一本书上看到了这段代码,它应该创建一个上下文管理器,帮助您以原子方式更改列表。如果出现异常,则不会应用任何更改。否则他们都会。例如:
try:
with Atomic(example_list) as atomic:
atomic.append(5)
atomic.pop(-2)
atomic[3] = 6
except Exception as err:
print(err)
像这样一切正常。我不明白的是 exit 的最后一行:
self.original[:] = self.modified
我知道它不会更改引用,而是在不更改引用的情况下更改原始列表中的值。但为什么不起作用:
self.original = self.modified
它将原始列表的引用更改为修改后的列表。所以它应该是指被修改的列表。但是当你像这样运行代码(没有切片)时,它不起作用。为什么?
解决方法
假设您没有制作就地副本。现在 self.original
指的是一个与之前不同的 list
对象。运行这段代码后
x = [1,2,3]
y = Atomic(x)
with y as atomic:
atomic.append(5)
atomic.pop(-2)
atomic[2] = 6 # No error,so the atomic operation succeeds
您不再有 x
和 y.original
指代同一个列表; x == [1,3]
,但y.original == [1,6]
。
或者您不知道 x[:] = y
实际上制作了就地副本? x = y
只是让 x
指代 y
指代的任何东西,而失去对先前 x
指代的任何指代。 x[:] = y
更像是
for i in range(len(x)):
x[i] = y[i]
,
如果不带[:]赋值,会在Atomic对象中改变一个指向这个可变对象的链接,但不会影响原来的可变变量
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。