📜  Python中的共享引用(1)

📅  最后修改于: 2023-12-03 14:46:39.501000             🧑  作者: Mango

Python中的共享引用

在Python中,对象的赋值和传递并不是简单的复制,而是共享引用。这意味着当两个变量引用同一个对象时,它们实际上指向同一个内存地址,因此,对其中一个变量所做的修改会对另一个变量产生影响。

赋值和传递

Python中的赋值符号(=)只是将对象的引用从一个变量复制到另一个变量,而并没有创建新的对象。例如:

a = [1, 2, 3]
b = a

在这个例子中,ab引用同一个列表,因此对a的修改也会影响到b

a.append(4)
print(b)  # [1, 2, 3, 4]

同样的,函数中的参数传递也是共享引用的。例如:

def modify_list(lst):
    lst.append(4)

a = [1, 2, 3]
modify_list(a)
print(a)  # [1, 2, 3, 4]

在这个例子中,a被传递给函数modify_list中,并在函数中被修改。修改后的lst引用了同一个列表对象,因此a也被修改了。

可变和不可变对象

在Python中,可变对象可以被修改,而不可变对象不可以被修改。例如,列表是一种可变对象,而元组是一种不可变对象。

当可变对象被共享引用时,修改一个变量也会影响到其他变量。例如:

a = [1, 2, 3]
b = a
a.append(4)
print(b)  # [1, 2, 3, 4]

当不可变对象被共享引用时,修改一个变量会创建一个新对象,而其他变量不受影响。例如:

a = (1, 2, 3)
b = a
a = a + (4,)
print(a)  # (1, 2, 3, 4)
print(b)  # (1, 2, 3)

在这个例子中,a原先引用了一个元组对象(1, 2, 3),然后a = a + (4,)创建了一个新元组对象(1, 2, 3, 4),并将a重新指向该对象。因此,b还是引用原来的元组对象(1, 2, 3)

内置函数中的共享引用

Python的一些内置函数也使用共享引用。例如,list()dict()set()函数创建的对象实际上是可变对象,因此传递到这些函数中的对象也是共享引用的。例如:

a = (1, 2, 3)
b = list(a)  # 创建一个新列表对象
a = a + (4,)
print(a)  # (1, 2, 3, 4)
print(b)  # [1, 2, 3]

在这个例子中,list()函数创建了一个新的列表对象,并将原来的元组对象(1, 2, 3)的元素复制到了新列表中。因此,ba引用了不同的对象,而不是共享引用。

总结

Python中的共享引用是一种重要的语言特性,可以帮助程序员编写更简洁、高效的代码。但是,共享引用也可能导致不必要的副作用,特别是在多线程环境下。因此,在编写Python程序时,应该充分了解共享引用的机制,并小心地处理好对象的赋值和传递。