python高阶应用——对象的引用

本文详细解释了Python中的对象引用机制,强调了变量存储的是对象引用而非值,以及浅拷贝与深拷贝的区别。讨论了可变对象如列表、字典的修改影响,以及不可变对象如整数、字符串的特性。
摘要由CSDN通过智能技术生成

在编程中,尤其是在像 Python 这样的语言中,对象的引用是指向内存中存储对象数据的指针或者内存地址。当你创建一个对象时,实际上是在内存中为该对象分配了一块空间,对象的引用就是访问这块空间的方式。

对象与引用

在 Python 中,变量不直接存储值,而是存储对象的引用。例如:

a = [1, 2, 3]

这里,a 不直接包含列表 [1, 2, 3],而是包含一个指向内存中存储这个列表的引用。如果你将 a 赋值给另一个变量:

b = a
print(id(a))  #a对象的地址:2761620989760
print(id(b))  #b对象的地址:2761620989760

现在,b 也包含指向同一个列表的引用。这意味着如果你修改 ba 也会受到影响,因为它们都指向同一个对象。

引用的影响

由于多个变量可以引用相同的对象,所以对对象的修改会通过所有引用该对象的变量可见。例如:

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

当我们调用 b.append(4) 时,列表 [1, 2, 3] 被修改为 [1, 2, 3, 4]。由于 ab 都引用同一个列表,所以这个修改对 a 也是可见的。

引用与拷贝

当你创建一个对象的拷贝时,理解引用的概念变得尤为重要。浅拷贝会创建一个新对象,但该对象中包含的是对原始对象中元素的引用,而不是元素本身的拷贝。这意味着如果原始对象中的元素是可变的,那么原始对象和拷贝对象中的这些可变元素实际上是同一个对象。

深拷贝,另一方面,会创建一个新对象,并且递归地复制原始对象中包含的所有对象,这样副本就完全独立于原始对象了。

引用的实际例子

举一个实际的例子来说明引用:

# 定义一个简单的类
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

# 创建一个 Point 对象
p1 = Point(10, 20)

# 创建一个引用 p1 的变量 p2
p2 = p1

# 修改 p2
p2.x = 30

# 查看 p1 的 x 属性
print(p1.x)  # 输出: 30

在上面的代码中,p1p2 引用同一个 Point 对象。当我们修改 p2.x 时,我们实际上修改的是 p1p2 共同引用的对象的状态,因此 p1.x 也变成了 30。

在 Python 中,对象可以被分类为可变(mutable)或不可变(immutable)对象,这个分类基于对象的状态是否可以在其生命周期中改变。

不可变对象(Immutable Objects)

不可变对象一旦被创建,其状态就不能改变。如果你尝试改变不可变对象的内容,实际上会创建一个新的对象。不可变对象包括:

  • 整数(int)
  • 浮点数(float)
  • 复数(complex)
  • 字符串(str)
  • 元组(tuple)
  • 冻结集合(frozenset)

这意味着,例如,当你拼接字符串或者修改元组时,Python 实际上是在创建一个新的对象,而不是在原地修改原有对象。这是因为字符串和元组等不可变对象不能被更改。

a = "Hello"
b = a
a += " World!"
print(a)  # 输出: Hello World!
print(b)  # 输出: Hello

在上面的例子中,a += " World!" 并没有改变原始字符串 "Hello",因为字符串是不可变的。相反,它创建了一个新的字符串 "Hello World!" 并更新了 a 的引用。

可变对象(Mutable Objects)

可变对象可以在其生命周期中改变。你可以在不创建新对象的情况下更改对象的内容。可变对象包括:

  • 列表(list)
  • 字典(dict)
  • 集合(set)

这些对象的内容可以被改变,例如:

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

在这个例子中,ab 引用同一个列表对象。使用 a.append(4) 向列表添加一个元素,这个改变也反映在 b 上,因为它们指向同一个列表对象。

总结一下:

  • 不可变对象:一旦创建,其内容不可改变。任何对对象内容的修改实际上都会创建一个新的对象。常见的不可变对象有整数、浮点数、字符串、元组等。
  • 可变对象:创建之后,其内容可以改变。对对象的修改是在原地进行的,不会创建新的对象,对象的引用不会发生改变。常见的可变对象有列表、字典、集合等。

对象的可变性对于理解对象如何被传递到函数、如何被存储以及如何被拷贝等方面非常重要。不可变对象提供了一定程度的安全性,因为它们不能被改变,这意味着它们可以被自由地共享和传递,而不用担心意外的修改。而可变对象则需要更小心地处理,因为它们的改变会影响所有引用该对象的地方。

  • 33
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值