Python attrs类属性缓存延迟加载

时间:2019-04-06 11:17:20

标签: 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)

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

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

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

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

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

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


一般不干净的解决方案是让一个@property带有一个吸气剂,吸气剂检查私有_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)

1 个答案:

答案 0 :(得分:1)

您退后一步时的问题是序列化之一。 Python的延迟加载方式确实是使用属性,因此您可以正确理解这一部分。

序列化(以及反序列化的问题)在这里和attrs错误跟踪器上都经常出现。问题在于,这是一个固有的复杂主题,这就是为什么我们决定在某些时候将其排除在范围之外,除非是简单的案例(例如,直接算词/ astuple),并让社区提出专门的库。

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

也就是说,如果这两种方法都不能满足您的需求,则可以使用attrs的extension machinery和元数据完全实现您的用例。我不确定您是否可以按自己的意愿执行命令,但是在最坏的情况下,您可以复制/粘贴并添加自己的逻辑。函数is quite simple