Подтвердить что ты не робот

Почему нельзя использовать эллипсис и NotImplemented?

Я с удивлением обнаружил, что python (версия 3.2.2) отказывается сортировать объект, потому что его dict содержал ссылку на Ellipsis. Из других встроенных констант, pickle рад работать с False, True и None, как явно указано в рассортировать документацию, но также дросселирует на NotImplemented.

Python 3.2.2 (default, Sep  5 2011, 21:17:14) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.dumps(True)
b'\x80\x03\x88.'
>>> pickle.dumps(False)
b'\x80\x03\x89.'
>>> pickle.dumps(None)
b'\x80\x03N.'
>>> pickle.dumps(Ellipsis)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'ellipsis'>: attribute lookup builtins.ellipsis failed
>>> pickle.dumps(NotImplemented)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'NotImplementedType'>: attribute lookup builtins.NotImplementedType failed

Для полноты менее полезных встроенных констант __debug__ является просто bool, поэтому не вызывает проблем; copyright, license и credits работают (их тип site._Printer); quit и exit do not (их тип site.Quitter, который не может быть найден, поскольку он определен внутри функции).

Может кто-нибудь объяснить, почему это - конечно Ellipsis и NotImplemented не просто были пропущены? Единственная релевантная информация, которую я могу найти, это эта ошибка, которая жалуется, что NoneType (т.е. type(None)) не поддается сортировке. Один из комментаторов упоминает, что type(Ellipsis) и type(NotImplemented) нельзя мариновать, очевидно, не замечая, что их экземпляры тоже не могут быть.

4b9b3361

Ответ 1

Нет никаких оснований для того, чтобы python не выделял такие вещи, как Ellipsis и NotImplemented, и, откровенно говоря, отсутствие их picklable способствует слабости python как параллельного/асинхронного языка. Вы можете рассортировать эти типы объектов с помощью dill, замены для pickle. Да, я знаю, что это мягкое разглагольствование, но я думаю, что NotImplemented в вашем целевом коде не должен помешать вам использовать multiprocessing или какой-либо другой из параллельного python... или сохранить состояние вашей сессии python для использования в более позднее время... или что-то еще.

Python 3.2.5 (default, May 19 2013, 14:25:55) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.dumps(True)
b'\x80\x03\x88.'
>>> dill.dumps(False)
b'\x80\x03\x89.'
>>> dill.dumps(None)
b'\x80\x03N.'
>>> dill.dumps(Ellipsis)
b'\x80\x03cdill.dill\n_eval_repr\nq\x00X\x08\x00\x00\x00Ellipsisq\x01\x85q\x02Rq\x03.'
>>> dill.dumps(NotImplemented)
b'\x80\x03cdill.dill\n_eval_repr\nq\x00X\x0e\x00\x00\x00NotImplementedq\x01\x85q\x02Rq\x03.'

Получить dill здесь: https://github.com/uqfoundation/dill

Ответ 2

Цитирование документации:

Можно мариновать следующие типы:

  • Нет, True и False
  • целые числа, числа с плавающей запятой, комплексные числа
  • строки, байты, bytearrays
  • кортежи, списки, наборы и словари, содержащие только выделяемые объекты
  • функции, определенные на верхнем уровне модуля
  • встроенные функции, определенные на верхнем уровне модуля
  • которые определены на верхнем уровне модуля
  • экземпляры таких классов, чья __dict__ или __setstate __() является picklable (подробности см. в разделе Экземпляры класса сортировки)

Два объекта, о которых идет речь, Ellipsis и NotImplemented, не соответствуют ни одному из этих правил и, следовательно, не могут быть маринованными.

Я сомневаюсь, что есть какая-то лучшая причина не включать все встроенные константы в первое правило, кроме того, что никто не видел необходимости в нем. Если вы действительно думаете, что pickle должен поддерживать это, подумайте о отправке запроса функции (лучше приведите убедительный вариант использования!).