我在这里已经阅读了很多关于这个主题但我仍然找不到合适的答案。 我有一个类:
class A(object):
def __init__(self, first, second):
self.first = first
self.second = second
def __eq__(self, other):
return ****
def __str__(self):
return *****
def __repr__(self):
return ****
a = A("a", "b")
我怎么能禁止a.first =“c”呢?
答案 0 :(得分:4)
您可以禁用__setattr__
作为初始化对象的最后一步。
class A(object):
def __init__(self, first, second):
self.first = first
self.second = second
self.frozen = True
def __setattr__(self, name, value):
if getattr(self, 'frozen', False):
raise AttributeError('Attempt to modify immutable object')
super(A, self).__setattr__(name, value)
>>> a = A(1, 2)
>>> a.first, a.second
(1, 2)
>>> a.first = 3
Traceback (most recent call last):
File "<pyshell#46>", line 1, in <module>
a.first = 3
File "<pyshell#41>", line 10, in __setattr__
raise AttributeError('Attempt to modify immutable object')
AttributeError: Attempt to modify immutable object
编辑:这个答案有一个缺陷,我确信每个其他解决方案都会共享:如果成员本身是可变的,那么没有什么可以保护它们。例如,如果您的对象包含列表,则它全部结束。这与C ++相反,即C ++声明对象const
以递归方式扩展到其所有成员。
答案 1 :(得分:3)
您可以覆盖__setattr__
以阻止任何更改:
def __setattr__(self, name, value):
raise AttributeError('''Can't set attribute "{0}"'''.format(name))
或阻止添加新属性:
def __setattr__(self, name, value):
if not hasattr(self, name):
raise AttributeError('''Can't set attribute "{0}"'''.format(name))
# Or whatever the base class is, if not object.
# You can use super(), if appropriate.
object.__setattr__(self, name, value)
您还可以使用对允许属性列表的检查来替换hasattr
:
if name not in list_of_allowed_attributes_to_change:
raise AttributeError('''Can't set attribute "{0}"'''.format(name))
另一种方法是使用属性而不是普通属性:
class A(object):
def __init__(self, first, second):
self._first = first
self._second = second
@property
def first(self):
return self._first
@property
def second(self):
return self._second