4

我的课程看起来像这样:

@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 并仅在实际调用序列化而不是 on 时初始化魔术属性来序列化__init__

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

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

b)只有当我实际调用它时才实例化 ImageMagic 对象。

c) 只有一次,以便以后如果多次调用它可以重用。

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


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

4

1 回答 1

2

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

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

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

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

于 2019-04-23T10:21:31.827 回答