我会试着澄清一下:
例如,我创建一个本地创建列表的函数,然后返回它。 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]]
此处,返回的列表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]]
已创建新列表l2
,但l
未受影响,这意味着它确实存在于函数外部,其子列表是它自己的,而不是对仍然存在于其中的子列表的引用功能体。
所以我的问题是:Python是否使用了深度复制或类似的东西来制作l
?
无论我使用函数返回什么类型的对象,它都不会受到后续调用此函数的影响?
(只要对象是在函数中本地创建的)
如果我不够清楚,请不要犹豫告诉我。 谢谢,
答案 0 :(得分:2)
当您第二次运行该功能时,整个功能将重新运行 - 它没有"内存中的内存; sublist1
为[1, 2, 3]
&#34 ;
您尚未复制列表[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]]
因为在这种情况下,python确实具有前一个结果的内存,并返回相同的对象
答案 1 :(得分:2)
这可能不会直接回答这个问题,但应该有助于澄清相关概念。
如果在函数内创建嵌套对象并将其返回,则该对象将继续存在。即使功能结束,它也不会超出范围。
示例代码
class Some_Class (object):
prop_x = None
def __init__(self, prop_x ):
self.prop_x = prop_x
def __repr__(self):
return "prop_x = "+repr (self.prop_x)
def fx ():
dict_x = { "k1" : "v1" }
print hex ( id (dict_x) )
obj1 = Some_Class ( prop_x = dict_x )
print hex ( id (obj1.prop_x) )
print "obj1 is "+repr( obj1 )
return obj1
recv_obj = fx ()
print "recv_obj is "+repr( recv_obj )
print hex ( id (recv_obj.prop_x) )
输出
0xdfaae0
0xdfaae0
obj1 is prop_x = {'k1': 'v1'}
recv_obj is prop_x = {'k1': 'v1'}
0xdfaae0
dict dict_x
被分配给Class对象prop_x
的{{1}}变量。 dict不会在内存中再次创建,但会发生obj1
。 soft copy
指向prop_x
的内存位置。
当您在此函数结束时返回对象dict_x
时,obj1
超出范围,但dict_x
仍然指向它所使用的内存地址0xdfaae0
在返回的对象prop_x
中。因此,dict值recv_obj
保留在内存中。
答案 2 :(得分:0)
Python中的变量是指向对象的指针。因此,函数将返回指向函数中创建的对象的指针,从而无需复制返回值。