Zaskoczyło mnie, że pyton (wersja 3.2.2) odmawiał wybrania obiektu, ponieważ jego dykcja zawierała odniesienie do Ellipsis
. Spośród innych built-in constants, pikle jest szczęśliwy pracy z False
, True
i None
, jak wyraźnie stwierdzono w pickle documentation, ale również dławiki na NotImplemented
.Dlaczego Ellipsis i NotImplemented nie mogą być marynowane?
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
Dla kompletności, z mniej przydatnych wbudowanych stałych, __debug__
tylko bool, więc nie powoduje żadnych problemów; copyright
, license
i credits
(ich typ to site._Printer
); quit
i exit
nie (ich typ to site.Quitter
, którego nie można znaleźć tak, jak jest zdefiniowany w funkcji).
Czy ktoś może wyjaśnić, dlaczego tak jest - z pewnością Ellipsis
i NotImplemented
nie zostały przeoczone? Jedyną istotną informacją, jaką mogę znaleźć, jest this bug, która narzeka, że NoneType
(tj. type(None)
) nie można wybrać. Jeden z komentatorów wspomina, że type(Ellipsis)
i type(NotImplemented)
nie mogą być marynowane, najwyraźniej nie zauważając, że ich instancje też nie mogą być.
Odd pominięcie, choć można by argumentować, że nie jesteś naprawdę powinien zachować odniesień do tych wartości na początek. – millimoose
@Inderdial: mój szczególny przypadek użycia był w kontenerze, który śledzi dostępne plasterki. Ponieważ plasterki mogą być marynowane, wydaje się dziwne, że Ellipsis (który jest tak naprawdę tylko specjalnym plasterkiem) nie może. Przechowywanie odniesienia do 'NotImplemented' jest prawdopodobnie mniej prawdopodobne, ale mogę sobie wyobrazić, że ktoś może tego chcieć dla jakiegoś skomplikowanego schematu porównywania. – James
@ James - Ściśle mówiąc, 'Ellipsis' nie jest specjalnym rodzajem plastra, ale jego interpretacja jest absolutnie zdefiniowana przez użytkownika. W Numpy jest to bardziej jak sekwencja zero lub więcej plasterków, określana automatycznie. –