在python中,返回在函数体中创建的对象会对其进行深层复制吗?

Yan*_*ann 5 python copy return-value deep-copy

我将尝试澄清:

例如,我制作了一个在本地创建列表并返回列表的函数。Python如何创建在函数体外部存在的返回列表?它是否使用“ deepcopy”(或类似的东西)?

In [50]: def create_list():
    ...:     sublist1 = [1,2,3]
    ...:     sublist2 = [4,5,6]
    ...:     list_of_lists=[sublist1,sublist1,sublist2]
    ...:     return list_of_lists
    ...: 

In [51]: l=create_list()

In [52]: l
Out[52]: [[1, 2, 3], [1, 2, 3], [4, 5, 6]]

In [53]: l[0].append(4)

In [54]: l
Out[54]: [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)

在这里,返回的列表l仍然包含子列表。并且l[0]并且l[1]仍然引用相同的子列表(这是正常的Python行为)。因此,复制了列表及其结构。

如果我再打一次电话create_list()

In [55]: l2=create_list()

In [56]: l2
Out[56]: [[1, 2, 3], [1, 2, 3], [4, 5, 6]]

In [57]: l
Out[57]: [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)

l2已创建一个新列表,但l不受影响,这意味着它确实存在于函数外部,并且其子列表是其自己的,而不是引用仍将存在于函数主体中的子列表。

所以我的问题是:Python是否使用了Deepcopy或类似的东西l?无论我使用函数返回哪种对象,它都不会受到随后对该函数的调用的影响吗?(只要对象是在函数中本地创建的)

如果我不够清楚,请不要犹豫告诉我。谢谢,

Eri*_*ric 3

当您第二次运行该函数时,整个函数将重新运行 - 它没有“上次,sublist1[1, 2, 3]的内存。

您尚未复制该列表[1, 2, 3]。您已经创建了两次。


请注意,如果您使用像 这样的缓存装饰器@functools.lru_cache,您会得到令人惊讶的结果:

>>> @lru_cache()
... def create_list():
...     sublist1 = [1,2,3]
...     sublist2 = [4,5,6]
...     list_of_lists=[sublist1,sublist1,sublist2]
...     return list_of_lists
...
>>> l = create_list(); l
[[1, 2, 3], [1, 2, 3], [4, 5, 6]]
>>> l[0].append(4); l
[[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]
>>> create_list()
[[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)

因为在这种情况下,python确实存储了之前的结果,并返回相同的对象