Это не рассол, это, во-первых, вы используете Latin-1.
Когда вы go с выхода pickle.dumps
, ie. b
в Out [46], значение, которое вы присваиваете b
в следующем операторе, затем вы изменили тип с bytes
на str
. То, как вы сделали это изменение, эквивалентно b = b.decode('latin1')
.
Например, исходный b
содержал последовательность b'(V\x9d^\x0f'
(в последней трети). Давайте используем его, чтобы увидеть, что произошло:
>>> b = b'(V\x9d^\x0f'
>>> b.decode('latin1')
'(V\x9d^\x0f'
Это то, что вы присвоили b
в Утверждении 47 (ближе к концу второй строки). Визуально , вы отбросили префикс b
строкового литерала. Фактически , вы расшифровали bytes
объект в str
, используя Latin-1. Это потому, что Latin-1 имеет отображение байтовых значений 1: 1 в кодовые точки Unicode.
Теперь это str
. Но для pickle нужен объект bytes
, поэтому вам нужно снова кодировать. Однако, если вы используете UTF-8 для кодирования, вы получите bytes
объект, отличный от исходного:
>>> b.decode('latin1').encode('utf8')
b'(V\xc2\x9d^\x0f'
Вместо \x9d
у вас теперь есть \xc2\x9d
.
Если вы кодируете с помощью Latin-1, вы получите то же, что и раньше:
>>> b.decode('latin1').encode('latin1')
b'(V\x9d^\x0f'
Но: Я не совсем понимаю, почему это преобразование в оба конца будет необходимо на всех. Там действительно нет необходимости декодировать вывод pickle.dumps
в str
. Вы можете просто хранить значение в байтовой строке все время. Используйте правильный тип: bytes
для двоичных данных (например, для дампа), str
для текста (в отличие от дампа).