我正在编写一个解析文件的库,创建一个代表该文件的对象,并允许将该对象导回文件。
我想验证每次更改这些值时都包含所需的标题和列。因此,我试图使用@property装饰器进行验证。
我在@property的python文档中注意到他们使用' _variable'如果属性名称为'变量'。据我所知,前面的单个下划线表示该变量仅供弱内部使用。但是,我认为@property装饰器的意思是任何设置变量的调用都会导致setter函数运行。
_headers = None
required_headers = ['FIELD_DELIM', 'VIDEO_FORMAT', 'FPS']
@property
def headers(self):
return self._headers
@headers.setter
def headers(self, value):
for header in self.required_headers:
if header not in value:
raise Exception
self._headers = value
虽然这段代码有效,但我知道我仍然可以通过执行myObject._headers = value来绕过我的setter。
有没有办法可以确保始终执行验证而不依赖于用户尊重_headers是供内部使用?
答案 0 :(得分:7)
Python并非旨在帮助您确保"没有人像这样误用你的对象。私有属性的下划线前缀,以及用于隐藏getter和setter背后属性的@property
机制,可以确保人们不应该使用您的对象,这很明显那些,并且让他们更难以意外,但它无法阻止他们真正恶意地这样做。
虽然有一些技巧可以用来更好地隐藏你的属性,但是在像Python这样高度动态,内省的语言中,总有一种方法可以直接在你的{{1或者隐藏它们的任何其他属性,或者只是将对象的__dict__
更改为限制较少的内容。
换句话说,您已经可以依赖用户尊重__class__
供内部使用,如果您担心的是您的用户是白痴;如果您担心它们是恶意的,那么Python就是您错误的语言。
答案 1 :(得分:2)
您可以使用双下划线进行名称修改或实现自定义描述符,但Python的核心原则之一是用户应该成年人同意#34;谁尊重接口,并尽力不做没有很好理由破坏接口的事情。基本上,不要担心它,只需使用单个下划线将数据存储在对象上。
答案 2 :(得分:1)
不,Python没有像Java那样强制执行私有与公共的概念
答案 3 :(得分:1)
如果您愿意,您可以实施__getattribute__
,在您尝试访问班级元素时进行检查,但即使这样也不是万无一失的。看看这个链接Difference between __getattr__ vs __getattribute__