[英]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
存儲為實例變量更有意義:使用對象的目的是避免必須傳遞變量,尤其是那些對象本身可以跟蹤的變量; 請注意,“首先計算幫助程序,然后根據它們計算屬性”的概念並不真正適用於此代碼:我們只需要在實際需要時評估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.