Python数据对象不可变性是如何实现的

来源:Python编程网作者:宋琮安头衔:草根站长
导读:本期聚焦于小伙伴创作的《Python数据对象不可变性是如何实现的》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Python数据对象不可变性是如何实现的》有用,将其分享出去将是对创作者最好的鼓励。

Python中的数据对象不可变性指的是对象创建之后,其内部存储的数据内容无法被修改,任何看似修改的操作都会生成一个新的对象实例。这种特性在很多场景下能避免意外的数据篡改,提升代码的可靠性。

Python数据对象不可变性是如何实现的

常见的不可变数据对象类型

Python内置的不可变数据对象主要包括数值类型(int、float、bool)、字符串str、元组tuple、冻结集合frozenset,以及字节串bytes。这些对象在创建之后,都无法直接修改其内部的值。

不可变对象与可变对象的对比

为了更清晰地理解不可变对象的特点,我们可以将其和可变对象做对比,具体差异如下:

对比维度不可变对象可变对象
创建后内容是否可改不可修改,修改会生成新对象可以直接修改内部内容
常见类型int、str、tuple、frozensetlist、dict、set、bytearray
哈希支持可以作为字典的键、集合的元素不能作为字典的键、集合的元素

不可变性的底层实现逻辑

1. 对象内部属性限制

Python的不可变对象在定义时,会将存储数据的核心属性设置为不可写状态。以整数int类型为例,其底层存储数值的属性没有暴露修改的接口,开发者无法直接对该属性赋值。

我们可以通过简单的代码验证这个特性:

# 尝试修改整数对象的属性会报错
num = 10
# int对象没有__dict__属性,无法动态添加或修改属性
try:
    num.value = 20
except AttributeError as e:
    print("修改整数属性失败:", e)

2. 操作符重载的限制

不可变对象的修改相关操作符都被重载为返回新对象的逻辑,而不是修改原有对象。比如字符串的拼接操作,不会修改原来的字符串,而是生成一个新的字符串对象。

下面的代码可以体现这个特点:

s1 = "hello"
s2 = s1 + " world"
# s1的值没有变化,s2是新生成的对象
print("s1的值:", s1)  # 输出 hello
print("s2的值:", s2)  # 输出 hello world
print("s1和s2是否是同一个对象:", s1 is s2)  # 输出 False

3. 元组等容器的不可变性实现

元组tuple的不可变性是指其存储的元素引用不可修改,但是元素本身如果是可变对象,那么该可变对象的内容还是可以修改的。元组的底层实现中,存储元素引用的数组被设置为不可变,无法替换其中的引用。

相关示例如下:

t = (1, [2, 3])
# 无法修改元组内的元素引用,下面这行代码会报错
try:
    t[0] = 2
except TypeError as e:
    print("修改元组元素引用失败:", e)

# 但是元组内的可变对象内容可以修改
t[1].append(4)
print("修改后的元组:", t)  # 输出 (1, [2, 3, 4])

4. 小整数池与字符串驻留机制

Python为了提升不可变对象的复用效率,还实现了小整数池和字符串驻留机制。小整数池会预先创建一定范围的整数对象,字符串驻留会让相同内容的字符串指向同一个对象,这从侧面强化了不可变对象的特性,因为相同值的对象本身就是同一个实例,修改任何一个都会影响所有引用,所以干脆不允许修改。

验证代码如下:

# 小整数池验证
a = 10
b = 10
print("a和b是否是同一个对象:", a is b)  # 输出 True

# 字符串驻留验证
s1 = "test"
s2 = "test"
print("s1和s2是否是同一个对象:", s1 is s2)  # 输出 True

自定义不可变数据对象

除了内置的不可变对象,我们还可以通过重写类的相关方法,自定义不可变的数据对象。核心是要禁止对象的属性修改,通常可以重写__setattr__方法,在属性赋值时抛出异常。

自定义不可变对象的示例如下:

class ImmutablePoint:
    def __init__(self, x, y):
        # 调用父类的__setattr__方法初始化属性,绕过自定义的__setattr__
        super().__setattr__("x", x)
        super().__setattr__("y", y)

    def __setattr__(self, name, value):
        # 禁止修改任何属性
        raise AttributeError("不可变对象,无法修改属性")

    def __repr__(self):
        return f"ImmutablePoint(x={self.x}, y={self.y})"

# 测试自定义不可变对象
p1 = ImmutablePoint(1, 2)
print("p1:", p1)  # 输出 ImmutablePoint(x=1, y=2)
# 尝试修改属性会报错
try:
    p1.x = 3
except AttributeError as e:
    print("修改自定义不可变对象属性失败:", e)

通过上述实现方式,我们就可以创建出符合自己需求的不可变数据对象,在需要保证数据不被意外修改的场景下使用。

Python不可变对象数据对象对象实现修改时间:2026-07-09 20:36:35

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。