что делает __getstate_manages_dict__?

Я работал над многопроцессорной обработкой и расширениями C++, и я не совсем понимаю функцию __getstate_manages_dict__ (я знаю, как ее использовать, но я не совсем уверен, как она работает). Документация boost/Python для поддержка рассола говорит следующее:

Автор класса расширения Boost.Python может предоставить метод __getstate__, не принимая во внимание возможность того, что: * его класс используется в Python в качестве базового класса. Скорее всего, dict экземпляров производного класса необходимо замариновать, чтобы правильно восстановить экземпляры. * пользователь напрямую добавляет элементы в __dict__ экземпляра. Опять же, __dict__ экземпляра необходимо замариновать.

Чтобы предупредить пользователя об этой весьма неочевидной проблеме, предусмотрено защитное ограждение. Если __getstate__ определено, а __dict__ экземпляра не пусто, Boost.Python проверяет, есть ли у класса атрибут __getstate_manages_dict__. Исключение возникает, если этот атрибут не определен:

Я видел несколько примеров, когда __dict__ объекта возвращается в __getstate__, а затем обновляется в __setstate__. Что это __dict__ имеет в виду? Является ли это атрибутом __dict__ объекта производного класса? Кроме того, почему этот dict должен обрабатываться явно, если pickle вызывает __init__ для создания нового объекта, а затем устанавливает атрибут?

Спасибо


person qwerty_99    schedule 22.07.2020    source источник


Ответы (1)


Я знаю, как его использовать, но я не совсем уверен, как это работает

Это логическое значение, которое по умолчанию равно False. Смысл в том, чтобы сообщить Boost, что реализация __getstate__/__setstate__ обрабатывает атрибут класса __dict__, чтобы информация не была потеряна в процессе травления.

Идея состоит в том, что Boost::Python на самом деле не может определить, правильно ли написан код, поэтому вместо этого вас заставляют перепрыгивать через это дополнительное препятствие, чтобы, если вы не знаете о проблеме, вы видели сообщение об ошибке - как они скажем, to alert the user to this highly unobvious problem.

Это не делает ничего волшебного. Это просто подтверждение того, что вы прочитали гарантию, так сказать.

В документации boost/Python для поддержки рассола говорится следующее:

Это просто объясняет причины, по которым важно учитывать содержимое __dict__, даже если вы не хотите собирать все атрибуты, которые вы явно установили в __init__ (например, потому что класс содержит ссылку на большой ресурс, который вы намерены загрузить каким-либо другим способом, или кэш результатов, или...). Короче говоря, экземпляры вашего класса могут содержать информацию, которую вы не ожидали, и с которой ваша __getstate__ реализация не сможет справиться, если только она не примет во внимание __dict__ экземпляра.

Отсюда предлагаемый практический совет: если требуется __getstate__, включите __dict__ экземпляра в возвращаемый объект Python.

Что это __dict__ имеет в виду? Является ли это атрибутом __dict__ объекта производного класса?

Это атрибут __dict__ экземпляра, для которого был вызван __getstate__. Это может быть экземпляр производного класса, если этот класс не переопределяет методы. Или это может быть экземпляр базового класса, который может иметь или не иметь дополнительные атрибуты, добавленные вне реализации класса.

Кроме того, почему этот dict должен обрабатываться явно, если pickle вызывает init для создания нового объекта, а затем устанавливает атрибут?

См. выше. Когда вы получаете атрибуты (чтобы можно было записать файл pickle), вам нужно убедиться, что вы действительно получили все необходимые атрибуты, иначе при восстановлении они будут потеряны. Жестко закодированная логика может пропустить некоторые.

person Karl Knechtel    schedule 22.07.2020
comment
Ах я вижу. Итак, у объекта есть атрибут dict, который содержит определенную информацию, и некоторые из них могут быть потеряны при травлении, и самый простой способ избежать этого — обновить dict с помощью getstate и setstate? - person qwerty_99; 22.07.2020
comment
Вы не обновляете __dict__ с ними; вы используете __dict__ для получения информации для возврата __getstate__. Вы можете изменить __dict__ объекта self внутри __setstate__ как способ установки атрибутов, но проще установить их обычным способом. - person Karl Knechtel; 23.07.2020