簡體   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