实例属性在Python3中可以不可变吗

dom

我想在其中设置实例属性__init__,然后禁止对其进行任何更改。Python OOP中是否有这样的机制?更具体地说,我正在使用Python 3.7。

在您否决其重复副本之前,请注意,我所谈论的是a的不变性,instance attribute而不是class instance像建议的类似问题标题所问的那样本身的不变性

拉屎

有多种选择,具体取决于您要执行的操作。

1.最终类型

使用mypy和Final来自类型typing_extensions仅使用mypy进行静态检查,而不是在运行时强制执行。

$ pip install typing_extensions

from typing_extensions import Final

class Spam:
    foo: Final[int]
    def __init__(self, foo):
        self.foo = foo

在撰写本文时,这应该可以工作,但是typing_extensions仍然是实验性质的,并且可能会改变。Guido本人一直在研究mypy,因此它甚至可能出现在标准库typing模块中。

2. @property

使用一种财产(可以规避,但可能并非偶然)-

没有二传手。您仍然必须将变量存储在某个地方。可能使用_-prefixed名称,或使用闭包,或直接在实例dict上使用vars(将绕过来自的描述符函数@property)。

class Spam:
    def __init__(self, foo):
        vars(self)['foo'] = foo
    @property
    def foo(self):
        return vars(self)['foo']

或使用setter检查它是否已经设置,并引发异常。这使您可以使用常规语法进行首次设置,但如果将其设置为,则可能不值得花时间__init__

3.子类元组

从继承tuple您必须使用__new__代替__init__您获得了真正的不变性,但是这些本身不再是属性,您必须使用整数下标(self[0]等)访问它们从继承tuple意味着您也可以获取所有元组方法,而这可能是您不想要的。

如果仍然需要点访问,则可以尝试创建一个collections.namedtuple,然后从其继承。

from collections import namedtuple

class Spam(namedtuple('Spam', 'foo')):
    def __new__(cls, foo):
        return super().__new__(cls, foo)
    def print_foo(self):
        print(self.foo)

当然,您可以通过这种方式继承更多方法。

另请参阅typing.NamedTuple

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

可以将此不可变属性转换为自动属性吗?

类实例是不可变的吗?

我们可以向JavaScript中的不可变对象添加属性吗?

ValueError() 是 python3 中 Exception 类的实例吗?

将可变属性作为Python中的不可变对象返回

为什么`object`类的实例在Python中是不可变的?

为什么可以在python 3中使用ctypes修改不可变字节对象?

包含随机对象变量的类(该类的实例)可以不可变吗?

在python中实例化类时可以引用实例属性吗?

Python静态不可变属性

在不可变中扩展属性

Swift可选的Array属性是不可变的吗?

可以公开不可变对象的状态吗?

您可以对Python3 NamedTuple属性有约束吗?

Python中的可变和不可变

列表推导中的变量是不可变的吗?

我可以在这个不可变的类中添加formJson和toJson吗?

可以使用解构来重新分配RUST中的不可变变量吗?

Python3 中的可变长度参数 (*args)

在 Python3 中交错多个可变长度列表

在Python3中遍历文件的行时可以使用tell()的替代方法吗?

我可以在kivy和python3中使用html&css吗?

Python3变量名称中的简单区别可以改变代码的运行方式吗?

可以说以下代码在Python3中实现了多态性吗?

我可以在python3中格式化文档字符串吗

在Python3中覆盖__repr __()吗?

困惑为什么在对不可变字符串的+ =运算符进行第二次评估后,它不会更改Python3中的id

为什么不可变对象的属性在Swift中是可变的?

可变的蚂蚁不可变属性