Python @property(设置方法)限制只能在__init__方法中设置数据
我想创建一个对象,在这个对象初始化的时候(也就是在__init__()
方法里)导入一些原始数据。不过,我希望从那时起这些数据只能读取,不能修改。我在考虑使用一个设置器属性self.raw_data
,并想要实现以下逻辑:
@raw_data.setter
def raw_data(self, dataframe):
<IF calling from __init__>?
self.__raw_data = df
有没有办法让这个设置器方法知道它是在__init__
里面被调用的?这样就可以阻止其他任何修改数据的尝试。
2 个回答
1
在raw_data
的设置方法里做的任何事情,都无法阻止直接给__raw_data
赋值。我建议你不要定义设置方法,而是直接用__raw_data
来初始化。这会阻止对raw_data
的写入,但对__raw_data
没有影响。
如果你想要更严格的限制,实际上选择不多。一个选择是用C或Cython来编写你的类。另一个选择更简单,但会有一些奇怪的副作用。这个选择是继承一个不可变的内置类型,比如tuple
,然后用__new__
来创建预初始化的实例,而不是用__init__
去改变它们的状态:
class Immutable(tuple):
__slots__ = [] # Prevents creation of instance __dict__
def __new__(cls, *whatever_args):
attribute1 = compute_it_however()
attribute2 = likewise()
return super(cls, Immutable).__new__(cls, attribute1, attribute2)
@property
def attribute1(self):
return self[0]
@property
def attribute2(self):
return self[1]
这样做会让你的对象变成不可变的,但奇怪的副作用是你的对象现在变成了元组。
1
你能做到的最接近的方式是,只允许在self._raw_data
还没有被设置的情况下进行设置,就像这个例子:
class Foo(object):
def __init__(self, dataframe):
self._raw_data = dataframe
@property
def raw_data(self):
return getattr(self, '_raw_data', None)
@raw_data.setter
def raw_data(self, dataframe):
if hasattr(self, '_raw_data'):
raise AttributeError, "Attribute is read-only")
self._raw_data = dataframe
这样一来,这个设置器基本上就没什么用,所以你可以用更少的代码来跳过它(这会让这个属性变成只读的):
class Foo(object):
def __init__(self, dataframe):
self._raw_data = dataframe
@property
def raw_data(self):
return self._raw_data
但是要注意,这些解决方案都无法阻止你直接设置_raw_data
。