python - 如何在 Python 中创建不可变对象(immutable对象)?

虽然我从来不需要这个,但让我感到震惊的是,在 Python 中创建一个不可变对象(immutable对象)可能有点棘手。你不能只覆盖 __setattr__ , 因为那样你甚至不能在 __init__ 中设置属性.对元组进行子类化是一种有效的技巧:

class Immutable(tuple):
    
    def __new__(cls, a, b):
        return tuple.__new__(cls, (a, b))

    @property
    def a(self):
        return self[0]
        
    @property
    def b(self):
        return self[1]

    def __str__(self):
        return "<Immutable {0}, {1}>".format(self.a, self.b)
    
    def __setattr__(self, *ignored):
        raise NotImplementedError

    def __delattr__(self, *ignored):
        raise NotImplementedError

但是你可以通过 self[0]self[1]访问 ab 变量,这很烦人。

这在纯 Python 中可行吗?如果没有,我将如何使用 C 扩展来做到这一点?

(仅适用于 Python 3 的答案是可以接受的)。

更新:

从 Python 3.7 开始,要走的路是使用 @dataclass装饰者,请参阅新接受的答案。

最佳答案

我刚刚想到的另一个解决方案:获得与原始代码相同的行为的最简单方法是

Immutable = collections.namedtuple("Immutable", ["a", "b"])

它并没有解决属性可以通过[0]等访问的问题,但至少它相当短并且提供了与pickle兼容的额外优势> 和 复制

namedtuple创建一个类似于我在 this answer 中描述的类型,即从 tuple 派生并使用 __slots__。它在 Python 2.6 或更高版本中可用。

https://stackoverflow.com/questions/4828080/

相关文章:

linux - 我们什么时候应该使用互斥锁,什么时候应该使用信号量

c - 将简单的套接字变成 SSL 套接字

linux - 防止 strace 缩写参数?

python - Python 是解释的,还是编译的,或者两者兼而有之?

python - `sorted(list)` 与 `list.sort()` 有什么区别?

python - NumPy 2d 数组的切片,或者如何从 nxn 数组 (n>m) 中提取 mxm

linux - 如何将第三列打印到最后一列?

python - Python 字典是哈希表的一个例子吗?

python - TransactionManagementError "You can' t 在使

linux - 如何从容器本身获取 Docker Linux 容器信息?