Атрибут класса Python attrs кэшировал ленивую загрузку - PullRequest
3 голосов
/ 06 апреля 2019

У меня есть классы, которые выглядят так:

@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, просматривая все атрибуты и инициализируя магический атрибут.только когда он действительно вызывается для сериализации, а не для __init__.

. Как правило, я действительно не хочу, чтобы библиотека Magic проверяла объект, поскольку это дорогостоящая операция ввода-вывода.

Цель:
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)

1 Ответ

2 голосов
/ 23 апреля 2019

Ваш вопрос, когда вы делаете шаг назад, связан с сериализацией. Способ отложенной загрузки Python действительно использует свойства, поэтому вы правильно поняли эту часть.

Проблема сериализации (и, тем более, десериализации) часто возникает и здесь, и на трекере ошибок attrs. Проблема заключается в том, что это по своей сути сложная тема, поэтому в какой-то момент мы решили не допускать ее к рассмотрению, за исключением простых случаев (т. Е. Прямой asdict / astuple), и позволить сообществу создавать специализированные библиотеки.

И действительно, есть куча библиотек для erialization [sd], которые вы можете найти в attrs wiki , но я не знаю, поддерживает ли какая-либо из них ваше правильное, но острое использование случай.

Тем не менее, если ни одна из них не решит вашу проблему, ваш вариант использования может быть полностью реализован с помощью механизма расширения attrs и метаданных. Я не уверен, что вы можете отклонить суждение по своей воле, но в худшем случае вы можете просто скопировать / вставить его и добавить свою собственную логику. Функция довольно проста .

...