[英]Python custom initialization on first class attribute access
目标是创建一个自定义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__
遇到了__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...
理想情况下,此方法可以处理各种不同的行为。
你有一个缓存装饰器memoize
,那么为什么不用它来缓存你的_expensive_date_attr
? 和BTW把它变成一个属性:
class LazyDateModule():
def __init__(self, args):
self.args = args
self._assembled = False
@memoize
@property
def _expensive_date_attr(self):
return date.today
@memoize
def date_str():
return str(self._expensive_date_attr)
@memoize
def month_num():
return self._expensive_date_attr.month
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.