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

标签 python python-2.7 lazy-loading lazy-evaluation

目标是创建一个自定义 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()

如何仅在第一次访问任何记忆化属性方法时运行 _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...

理想情况下,此方法将处理各种不同的行为。

最佳答案

你有一个缓存装饰器memoize,那么为什么不用它来缓存你的_expensive_date_attr呢?顺便说一句,把它变成一个属性:

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

关于一流属性访问的 Python 自定义初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43592243/

相关文章:

python - 创建一个Python列表字典

python - (Z3Py) 声明函数

python - 如何找到 matplotlib 样式名称?

python - 当我使用python打开URL(维基百科)时,如何得到“ERR_ACCESS_DENIED”?

jquery - 如何仅在用户滚动到图像时加载图像

html - 棘手的延迟加载问题

python - 从大目录中随机延迟加载文件

python - 有没有可能为动态语言创建编译器而不失去他的动态特性?

Python如何强制一个字符串匹配另一个字符串的格式

python-2.7 - 使用 Pandas 时出现属性错误 : Python 2. 7