首页 > 后端开发 > Python教程 > Python 中的不可变类型与可变类型:子类化何时会破坏不可变性?

Python 中的不可变类型与可变类型:子类化何时会破坏不可变性?

Linda Hamilton
发布: 2025-01-01 08:09:10
原创
548 人浏览过

Immutable vs. Mutable Types in Python: When Does Subclassing Break Immutability?

不可变类型与可变类型:更深入的理解

不可变类型和可变类型之间的差异可能会引起混乱,尤其是当它出现时某些继承自不可变类型的类。

不可变类型:设计不变

在 Python 中,不可变类型是指其值无法就地修改的对象。不可变对象一旦创建,就保持不变;任何修改它的尝试都会产生一个新对象。例如,浮点对象是不可变的,这意味着它不能直接更改。

子类化不可变类型:创建可变性的幻象

但是,可以创建看似可变的不可变类型的子类。这是通过重写 __new__ 方法来实现的。例如,RoundFloat 类是 float 的子类,它将其值四舍五入到小数点后两位:

class RoundFloat(float):
    def __new__(cls, val):
        return float.__new__(cls, round(val, 2))
登录后复制

虽然此代码定义了一个继承自 float 的新类,但 RoundFloat 对象仍然是不可变的。这是因为 __new__ 方法只是创建一个具有舍入值的新浮点对象,并且它不会更改原始浮点对象。

可变类型:内部更改

相反,可变类型允许直接修改它们的值。定义方法的类可以被认为是可变的。例如,SortedKeyDict 类继承自 dict 并定义 example() 方法:

class SortedKeyDict_a(dict):
    def example(self):
        return self.keys()
登录后复制

该类允许在提供的方法中修改其值。但是,需要注意的是,SortedKeyDict 类本身仍然是不可变的。它的值可以更改,但底层实例保持不变。

在实践中理解可变性

为了更好地理解不可变类型和可变类型之间的区别,请考虑以下内容设想。使用 __new__ 将集合 d 传递给 SortedKeyDict 类会引发错误,而使用 __new__ 将其传递给 RoundFloat 类则不会。

d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))

SortedKeyDict.__new__(cls, d)  # Error raised
RoundFloat.__new__(cls, 12)  # No error
登录后复制

这说明 SortedKeyDict 是可变的,而 RoundFloat 是不可变的。由于 SortedKeyDict 是可变的,因此可以在其方法中就地修改它。相比之下,RoundFloat 是不可变的,因此将其传递给 __new__ 不会修改原始对象。

以上是Python 中的不可变类型与可变类型:子类化何时会破坏不可变性?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板