【问题标题】:Python attrs class attribute cached lazy loadPython attrs 类属性缓存延迟加载
【发布时间】:2019-08-28 03:12:21
【问题描述】:

我的课程看起来像这样:

@attr.s
class ImageMagic(object):
    path = attr.ib()

    _img = attr.ib()

    @_img.default
    def _img(self):
        return Image.open(self.path)

@attr.s
class FileObject(object):
    # Standard
    path = attr.ib()

    # When magic-ed
    magic = attr.ib(default=None)

我的目标是让 attrs.asdict() 能够序列化 FileObject,方法是遍历所有 attrs 并仅在实际调用序列化而不是在 __init__ 上初始化魔术属性。

在大多数情况下,我真的不希望 Magic 库检查对象,因为这是一项昂贵的 IO 操作。

目标:
a) 如何连接两个类

b) 只有在我实际调用 ImageMagic 对象时才具有魔法属性。

c) 只有一次,以便以后调用多次时可以重复使用。

有了这个,我更喜欢使用 Attrs 库。


一般不干净的解决方案是使用带有 getter 的 @property,getter 检查私有 _magic 属性是否存在,如果不存在则加载。

然后以某种方式将属性注册到 attrs 库,以便进一步序列化。

这是一个实际解决方案的示例:

@attr.s
class IOExpensiveClass(object):
    path = attr.ib()

    _hash = attr.ib()

    @_hash.default
    def _img(self):
        return IOOPERATION(self.path)


@attr.s
class FileObject(object):
    # Standard
    path = attr.ib()

    _magic = None

    # Missing attrs registration, that I yet don't know how to write
    @property
    def magic(self):
        return self._magic or IOExpensiveClass(self.path)

【问题讨论】:

  • 另一个不太干净的解决方案是覆盖 getattr,捕获对magic 的访问并在那里进行惰性评估。
  • 哦,是的,我光看评论就觉得很脏 :)))
  • 你可以使用这样的东西来进行惰性属性评估:gist.github.com/waszil/171d64e5b94cdd51c404d41332f476c0

标签: python python-attrs


【解决方案1】:

退后一步时,您的问题是序列化问题。 Python 的延迟加载方式确实是使用属性,所以你做对了。

序列化(尤其是反序列化)问题在此处和 attrs 错误跟踪器中不断出现。问题在于它是一个固有的复杂主题,这就是为什么在某些时候我们决定将其排除在范围之外,除了简单的情况(即直接 asdict/astuple),并让社区提出专门的库。

确实有一堆用于 [sd] 序列化的库,您可以在 attrs wiki 中找到它们,但我不知道它们中的任何一个是否支持您的有效但前卫的用例。

也就是说,如果两者都不能满足您的需求,您的用例完全可以使用 attrs 的extension machinery 和元数据来实现。我不确定你是否可以屈服于你的意愿,但在最坏的情况下,你可以复制/粘贴它并添加你自己的逻辑。函数is quite simple

【讨论】:

    猜你喜欢
    • 2014-04-12
    • 2013-07-03
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多