目標是創建一個自定義python類,它允許對屬性進行延遲加載(這裏有一個相當常見的問題,這裏有各種不同的解決方案),但是一次只運行昂貴的初始化步驟懶惰的訪問。這裏有一個例子:對第一類屬性訪問的Python自定義初始化
class LazyDateModule()
def __init__(self, args):
self.args = args
self._expensive_date_attr = None
def _expensive_init():
time.sleep(10)
self._expensive_date_attr = date.today()
@memoize
def date_str():
return str(self._expensive_date_attr)
@memoize
def month_num():
return self._expensive_date_attr.month
在這個例子中,我@memoize
裝飾處理我的緩存一步。
如果我在其他地方定義我LazyDateModule:
LDM = LazyDateModule()
如何只在第一次任memoized屬性方法進行訪問運行_expensive_init()
?我試過這樣的事情:
class LazyDateModule()
def __init__(self, args):
self.args = args
self._assembled = False
self._expensive_date_attr = None
def _expensive_init():
time.sleep(10)
self._expensive_date_attr = date.today()
self._assembled = True
@memoize
def date_str():
if self._assembled is False:
self._expensive_init()
return str(self._expensive_date_attr)
@memoize
def month_num():
if self._assembled is False:
self._expensive_init()
return self._expensive_date_attr.month
但這不是很乾淨。理想情況下,我希望這種行爲要麼在班級級別上 - 但是我試圖覆蓋__getattr__
或__getattribute__
。另一個裝飾者也會工作。
如果上述內容令人困惑,我很抱歉。讓我知道,如果我能以任何方式澄清它!編輯1: 我認爲上面的例子有點太簡單了。假設我的_expensive_init()做了一堆東西,而不是隻定義一個屬性。
def _expensive_init(self):
time.sleep(5)
self._expensive_date_attr = date.today()
time.sleep(1)
# send a message to someone saying that this occurred
time.sleep(1)
# run a db call to update when this action occurred
etc...
理想情況下,此方法將處理各種不同的行爲。
我寫了一個類似的模塊。我決定不完成它。它分兩步工作。在第一步中,一個簡單的方法裝飾器通過向裝飾函數本身添加一個屬性來註冊每個要記憶的方法。這個階級本身並不存在,所以這就是它所能做到的。在第二步中,類裝飾器檢查所添加屬性的所有方法,創建表,從類中移除這些方法,並安裝一個自定義的__getattr__來捕獲對錶中名稱的第一次訪問,調用該函數並添加結果作爲常規屬性。希望能幫助到你。 – VPfB