在python中,两个名称指向同一个对象



考虑以下示例:

class Test:
def __init__(self, lis: list):
self.list = lis

lis = [1, 2, 3]
obj1 = Test(lis)
obj2 = Test(lis)
print(obj1 is obj2)
print(obj1.list is obj2.list)
obj1.list.reverse()
print(obj2.list)

输出:

False
True
[3, 2, 1]

解释

我创建了两个相同类的对象;列表";每个对象的ID为CCD_ 1。测试名称obj1obj2是否引用同一对象,答案为否定(False(。但当我测试obj1.list is obj2.list时,我们得到了"True"作为答案。因此,当我反转名称obj1的列表时,该列表也反转了名称obj2,因为这是两个名称的相同列表。

我需要的是一种方法来反转obj1的列表,而不是obj2的列表。所以我需要创建一个新的列表。

最终,这将是一个结果:

obj1.list.reverse()
print(obj2.list)

预期输出:

[1, 2, 3]

您正在[1, 2, 3]0中存储对列表的相同引用,您可以通过复制来避免:

class Test:
def __init__(self, lis: list):
self.list =lis[:]

把它看作一个指针。因此,当您修改其中一个时,指向相同值的另一个也会发生更改。

Python中的copy method返回一个shallow copy of a list。浅拷贝意味着:在新列表中所做的任何修改都不会影响原始列表。

例如:

lis1=['a','b','c']
print(lis1)
lis2=lis1
print(lis2)
lis1.pop()
print(lis1, lis2)

输出为:

['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b'] ['a', 'b']

在该示例中,lis1lis2指代相同的地址。因此,它们中任何一个的任何变化都会导致另一个的变化。

我们可以使用列表的copy method或使用copy module来解决这个问题。

例如:

lis1=['a','b','c']
print(lis1)
lis2=lis1.copy()
print(lis2)
lis1.pop()
print(lis1, lis2)

输出:

['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b'] ['a', 'b', 'c']

在本例中,lis2是存储在不同地址的lis1的副本,因此当我们更改lis1时,在lis2中看不到任何更改。

同样,复制模块也可以使用。例如:

import copy
lis1=['a','b','c']
print(lis1)
lis2=copy.copy(lis1)
print(lis2)
lis1.pop()
print("list1=",lis1,"list2=", lis2)

输出:

['a', 'b', 'c']
['a', 'b', 'c']
list1= ['a', 'b'] list2= ['a', 'b', 'c']

同样,您的问题也可以使用copy method来解决。

class Test:
def __init__(self, lis: list):
self.list = lis
lis = [1, 2, 3]
obj1 = Test(lis)
obj2 = Test(lis)
obj2new=obj2.list.copy()
print(obj1 is obj2)
print(obj1.list is obj2.list)
obj1.list.reverse()
print(obj2new)

现在,返回所需的输出:

False
True
[1, 2, 3]

希望这有帮助!

相关内容

  • 没有找到相关文章

最新更新