Декодирование байтов по определению создает «Юникод» (на самом деле текст, где Юникод - это то, как вы можете хранить произвольный текст, поэтому Python использует его внутренне для всего текста), поэтому, когда вы говорите «Как список может содержать символы Юникода, если он имеет уже был расшифрован? это выдает фундаментальное недопонимание того, что такое Юникод. Если у вас есть str
в Python 3, это текст, и этот текст состоит из серии кодовых точек Unicode (с неопределенной внутренней кодировкой; фактически современные Python хранят в ASCII, latin-1, UCS-2 или UCS -4, в зависимости от наивысшего порядкового значения, а также иногда от кэширования представления UTF-8 или собственного представления wchar
для использования с устаревшими модулями расширения).
Вы видите repr
символа nul (порядковый номер Unicode 0) и думаете, что он не декодируется должным образом, и вы, вероятно, правы (нет ничего противозаконного в символах nul, они просто не распространены в простой текст); Ваши входные данные почти наверняка закодированы в UTF-16-LE, а не в UTF-8. Используйте правильный кодек, и текст выходит правильно:
>>> bs = bytearray(b'I\x00n\x00t\x00e\x00l\x00(\x00R\x00)\x00')
>>> bs.decode('utf-16-le') # No need to replace things, this is legit UTF-16-LE
'Intel(R)'
>>> list_of_dict = [{'name': _}]
>>> list_of_dict
[{'name': 'Intel(R)'}]
Дело в том, что, хотя создание нулевых символов является законным, если это не двоичный файл, скорее всего, его не будет, и если вы получаете их, вы, вероятно, выбрали неправильный кодек.
Расхождение между печатью str
и отображением является частью list
/ dict
из-за того, что list
/ dict
совпадает с repr
их содержимого (то, что вы наберете во многих случаях программно воспроизводить объект), поэтому строка выводится с экранированием \x00
. print
непосредственное использование str
не включает repr
, поэтому символы nul отображаются в виде пробелов (поскольку для nul нет печатаемых символов, поэтому ваш терминал решил отобразить его как пробелы).