繁体   English   中英

第一类属性访问的Python自定义初始化

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM