我想在其中设置实例属性__init__
,然后禁止对其进行任何更改。Python OOP中是否有这样的机制?更具体地说,我正在使用Python 3.7。
在您否决其重复副本之前,请注意,我所谈论的是a的不变性,instance attribute
而不是class instance
像建议的类似问题标题所问的那样本身的不变性。
有多种选择,具体取决于您要执行的操作。
使用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
模块中。
使用一种财产(可以规避,但可能并非偶然)-
没有二传手。您仍然必须将变量存储在某个地方。可能使用_
-prefixed名称,或使用闭包,或直接在实例dict上使用vars
(将绕过来自的描述符函数@property
)。
class Spam:
def __init__(self, foo):
vars(self)['foo'] = foo
@property
def foo(self):
return vars(self)['foo']
或使用setter检查它是否已经设置,并引发异常。这使您可以使用常规语法进行首次设置,但如果将其设置为,则可能不值得花时间__init__
。
从继承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] 删除。
我来说两句