Python attrs 类属性缓存延迟加载

Boj*_*vic 5 python python-attrs

我的课程看起来像这样:

@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)
Run Code Online (Sandbox Code Playgroud)

我的目标是让 attrs.asdict() 能够FileObject通过遍历所有 attrs 并仅在实际调用序列化而不是在调用时初始化 magic 属性来序列化__init__

大多数时候我真的不希望 Magic 库检查对象,因为这是一个昂贵的 IO 操作。

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

b)具有 magic 属性,仅在我实际调用 ImageMagic 对象时实例化它。

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

有了这个,我更愿意使用 Attrs 库。


一般不干净的解决方案是使用一个@property带有 getter 的 getter,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)

Run Code Online (Sandbox Code Playgroud)

hyn*_*nek 3

退一步来说,你的问题是序列化问题。Python 的延迟加载方式确实是使用属性,所以这部分是正确的。

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

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

也就是说,如果两者都不能满足您的需求,那么您的用例完全可以使用 attrs 的扩展机制和元数据来实现。我不确定你是否可以随心所欲,但在最坏的情况下,你可以复制/粘贴它并添加你自己的逻辑。功能相当简单