繁体   English   中英

仅限于__init__方法中设置数据的Python @property(setter方法)

[英]Python @property (setter method) that is restricted to setting data only in the __init__ method

我想设置一个在对象的初始化阶段(即在__init__()方法期间__init__()导入一些raw_data的对象。 但是,从那时起,我只想读它。 我正在考虑使用具有以下逻辑的setter属性self.raw_data

@raw_data.setter
def raw_data(self, dataframe):
    <IF calling from __init__>?
        self.__raw_data = df

setter方法是否有办法知道是否正在__init__中调用它? 阻止所有其他尝试更改数据的尝试。

您可以获得的最接近的结果是仅允许设置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

这使得setter几乎没有用,因此您可以通过更少的代码跳过它而获得相同的结果(这将使属性变为只读):

class Foo(object):
    def __init__(self, dataframe):
        self._raw_data = dataframe

    @property
    def raw_data(self):
         return self._raw_data

但是请注意,这些解决方案都不能阻止您直接设置_raw_data

您在raw_data setter中所做的任何事情都不会停止对__raw_data直接分配。 我建议不要定义setter并使用__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]

这使您的对象不可变,但是尴尬的副作用是您的对象现在是元组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM