簡體   English   中英

定義在初始化時按順序計算屬性的類的最佳實踐

[英]Best practice for defining a class that computes attributes in order when initialized

我想定義一個執行以下操作的類:

Class computer():
    def __init__(self, x):
        # compute first the 'helper' properties
        self.prop1 = self.compute_prop1(x)
        self.prop2 = self.compute_prop2(x)
        # then compute the property that depends on 'helpers'
        self.prop3 = self.compute_prop3(x)

    def compute_prop1(self, x):
        return x
    def compute_prop2(self, x):
        return x*x
    def compute_prop3(self, x):
        return self.prop1 + self.prop2

然后,當我初始化一個實例時,我會按順序計算所有屬性(首先是助手,然后是一切取決於助手):

>>> computer = Computer(3)
>>> computer.__dict__
{'prop1': 3, 'prop2': 9, 'prop3': 12}

但是,我認為編寫此代碼有更好的做法,例如使用裝飾器。 你能給我一些提示嗎? 謝謝!

這是您使用屬性的類(添加了用於返回每個屬性的方法):

Class PropertyComputer:
    def __init__(self, x):
        self._x = x

    @property
    def prop1(self):
        return self._x

    @property
    def prop2(self):
        return self._x * self._x

    @property
    def prop3(self):
        return self.prop1 + self.prop2

    def get_props(self):
        return self.prop1, self.prop2, self.prop3

在設計方面,我相信這更好,因為:

  • x存儲為實例變量更有意義:使用對象的目的是避免必須傳遞變量,尤其是那些對象本身可以跟蹤的變量;
  • 屬性賦值及其相應的計算捆綁在每個屬性修飾的方法中:我們永遠不必考慮問題是在 init 方法(定義屬性的地方)還是計算方法(其中的邏輯)屬性的計算被列出)。

請注意,“首先計算幫助程序,然后根據它們計算屬性”的概念並不真正適用於此代碼:我們只需要在實際需要時評估prop3 如果我們從不訪問它,我們就永遠不需要計算它。

與您的示例相比,使用屬性的“壞”副作用是這些屬性不會“存儲”在任何地方(因此我添加了最后一個方法):

c = PropertyComputer(x=2)
c.__dict__  # outputs {'_x': 2}

另請注意,使用裝飾器,屬性在您訪問它們時即時計算,而不是在 init 方法中僅計算一次。 以這種方式,屬性修飾的方法像方法一樣工作,但像屬性一樣訪問(這是使用它們的全部意義):

c = PropertyComputer(x=2)
c.prop1  # outputs 2
c._x = 10
c.prop1  # outputs 10

作為旁注,您可以使用functools.cached_property來緩存對這些屬性之一的評估,以防計算成本很高。

我認為以下是避免冗余的最簡單方法

class computer():
    def __init__(self, x):
        self.prop_dict = self.compute_prop_dict(x)

    def compute_prop_dict(self, x):
        prop1 = x
        prop2 = x*x
        return {'prop1': prop1, 'prop2': prop2, 'prop3': prop1 + prop2}

因此,實例化后的任何內容都可以通過prop_dict訪問這些助手

但正如 Brian 在評論中所說,這個命令只是 Python 3.7 的語言規范

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM