在遇到数据类之前,我一直使用namedtuples来表示不可变的数据结构,在我的用例中我更喜欢数据类(与问题无关)
现在我明白了,它们不是一成不变的!至少严格来说不是这样
setattr(frozen_dc_obj, "prop", "value")
引发异常。好的。
但是object.__setattr__(frozen_dc_obj,..)
为什么起作用呢
与namedtuple
相比,它引发了一个异常
from collections import namedtuple
from dataclasses import dataclass
NTTest = namedtuple("NTTest", "id")
nttest = NTTest(1)
setattr(nttest, "id", 2) # Exception
object.__setattr__(nttest, "id", 2) # Exception
@dataclass(frozen=True)
class DCTest:
id: int
dctest = DCTest(1)
setattr(dctest, "id", 2) # Exception
object.__setattr__(dctest, "id", 2) # WORKS
python Discord频道上的其他人给出了另一个伟大的见解:
冻结的数据类可能通过其自身的setattr限制访问,您可以通过将其传递给对象来绕过setattr
命名元组是从实际元组而不是python中的实现派生的,因此它们可以“真正”不可变,但是如果您在接口中使用数据类(同样可以以更混乱的方式对元组进行处理),这是一个没有意义的点。 我建议使用NamedTuple,而不是在NamedTuple上键入,因为它提供了作为一个适当类的可读性,但是如果您需要dataclass,那么冻结的类就可以了。NamedTuple实际上不是一个typehint,但在类定义中与它们一起工作,就像dataclasses一样,与类构造函数相比,它的定义更简洁
我认为在纯python中并没有限制所有访问的方法,因为您可以调用对象的方法
在元组上赋值将涉及到在c级别与(c)python交互,但这在某种意义上是相同的,因为它不是它的预期接口
Python总体上不太重视安全性,如果不应该做一些事情,那么如果用户做了,那就是用户的问题
namedtuple定义了^{} ,因此您不能设置任何属性(它没有
__dict__
)Frozen dataclasses另一方面,在^{} 方法中执行手动检查,如果是冻结的实例,则引发异常
比较以下各项:
相关问题 更多 >
编程相关推荐