我认为无论何时将对象传递给函数,它都会自动为您创建一个单独的副本,您可以在不更改原始文件的情况下进行修改。但是,以下代码每次都会以此错误终止。
>>> testvar = ['a' for a in range(100000)]
>>> def func(arg):
while arg is testvar:
arg.pop()
>>> func(testvar)
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
thing(m)
File "<pyshell#43>", line 3, in thing
obj.pop()
IndexError: pop from empty list
答案 0 :(得分:2)
&#34;我认为无论何时将对象传递给函数,它都会自动为您创建一个单独的副本,您可以在不更改原始文件的情况下进行修改。&#34;
嗯,你的假设是错误的。变量通过引用传递,而不是值。这包括如果您将参数的默认值设置为空列表,并在函数中更改它,下次您尝试使用该默认值时,它将不再是一个空列表。def foo(bar=[]):
bar.append("baz")
foo()
foo()
# bar is now ["baz", "baz"]
答案 1 :(得分:2)
来自:https://docs.python.org/3.4/library/copy.html
Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变或包含可变项的集合,有时需要一个副本,因此可以更改一个副本而不更改另一个副本。该模块提供了通用的浅层和深层复制操作(如下所述)。
当您调用函数时,您正在执行以下操作:
func(arg=testvar)
如果您想拥有数据的实际副本,可以将功能修改为以下内容:
def func(arg):
arg_copy = arg[:]
# mutate arg_copy here without mutating arg