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

Two names points to the same object in 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]

解释:

我创建了2个相同的对象class,每个对象的“列表”是[1, 2, 3]。测试名称 obj1obj2 是否引用同一个对象,答案是否定的 (False)。但是当我测试 obj1.list is obj2.list 时,当我反转名称 obj1 的列表时,我们得到 'True' 作为 answer.Thus,该列表也反转了名称 obj2,因为它是两个名称的相同列表。

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

最后会是这样的结果:

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

预期输出:

[1, 2, 3]

您正在 self.list 中存储对列表的相同引用,您可以通过复制来避免这种情况:

class Test:
    def __init__(self, lis: list):
        self.list = <b>lis[:]</b>

将其视为指针。因此,当您修改一个时,指向相同值的另一个也会更改。

Python中的copy methodreturns一个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 指的是同一个地址。因此,其中任何一个的任何变化都会导致另一个的变化。

我们可以使用list的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]

希望对您有所帮助!