В чем разница между кодированием / декодированием?

Я никогда не был уверен, что понимаю разницу между декодированием str / unicode и кодированием.

я знаю это str().decode() это когда у вас есть строка байтов, которая, как вы знаете, имеет определенную кодировку символов, учитывая, что это имя кодировки будет возвращать строку Unicode.

я знаю это unicode().encode() преобразует символы Unicode в строку байтов в соответствии с заданным именем кодировки.

Но я не понимаю что str().encode() а также unicode().decode() для. Может кто-нибудь объяснить, и, возможно, также исправить что-то еще, что я ошибся выше?

РЕДАКТИРОВАТЬ:

Несколько ответов дают информацию о том, что .encode делает на строку, но никто, кажется, не знает, что .decode делает для Unicode.

8 ответов

Решение

decode Метод строк Unicode на самом деле вообще не имеет приложений (если у вас по какой-то причине нет нетекстовых данных в строке Unicode - см. ниже). Я думаю, что в основном это происходит по историческим причинам. В Python 3 это полностью исчезло.

unicode().decode() будет выполнять неявное кодирование s используя кодек по умолчанию (ascii). Проверьте это так:

>>> s = u'ö'
>>> s.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

>>> s.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

Сообщения об ошибках точно такие же.

За str().encode() это наоборот - он пытается неявное декодирование s с кодировкой по умолчанию:

>>> s = 'ö'
>>> s.decode('utf-8')
u'\xf6'
>>> s.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)

Используется как это, str().encode() тоже лишнее.

Но есть другое применение последнего метода, который полезен: существуют кодировки, которые не имеют ничего общего с наборами символов и, таким образом, могут быть применены к 8-битным строкам осмысленным образом:

>>> s.encode('zip')
'x\x9c;\xbc\r\x00\x02>\x01z'

Вы правы, хотя: неоднозначное использование "кодирования" для обоих этих приложений... удивительно. Опять же, с отдельным byte а также string типы в Python 3, это больше не проблема.

Представление строки Юникода в виде строки байтов называется кодированием. использование u'...'.encode(encoding),

Пример:

    >>> u'æøå'.encode ('utf8') '\ xc3 \ x83 \ xc2 \ xa6 \ xc3 \ x83 \ xc2 \ xb8 \ xc3 \ x83 \ xc2 \ xa5' >>> u'æøå'.encode ('latin1') '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5' >>> u'æøå'.encode ('ascii') UnicodeEncodeError: кодек "ascii" не может кодировать символы в позиции 0-5: ординал не в пределах досягаемости (128)

Обычно вы кодируете строку Unicode всякий раз, когда вам нужно использовать ее для ввода-вывода, например, передавать ее по сети или сохранять в файл на диске.

Преобразование строки байтов в строку Unicode называется декодированием. использование unicode('...', encoding) или '...'. декодировать (кодировать).

Пример:

   >>> ты
   u '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5' # интерпретатор печатает объект Unicode следующим образом
   >>> Юникод ('\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5', 'latin1')
   и '\ xc3 \ xa6 \ xc3 \ XB8 \ xc3 \ xa5'
   >>> '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'.decode (' latin1 ')
   и '\ xc3 \ xa6 \ xc3 \ XB8 \ xc3 \ xa5'

Обычно вы декодируете строку байтов всякий раз, когда вы получаете строковые данные из сети или из файла на диске.

Я считаю, что в Python 3 есть некоторые изменения в обработке Unicode, поэтому вышеприведенное, вероятно, не правильно для Python 3.

Несколько хороших ссылок:

anUnicode.кодирование('кодирование') приводит к строковому объекту и может быть вызвано для объекта Unicode

строка.decode('encoding') приводит к объекту Unicode и может быть вызван на строку, закодированную в данной кодировке.


Еще несколько объяснений:

Вы можете создать некоторый объект Unicode, который не имеет никакой установленной кодировки. То, как он хранится в памяти Python, не имеет значения. Вы можете искать его, разбивать его и вызывать любую функцию управления строками, которая вам нравится.

Но наступает момент, когда вы хотите распечатать объект Unicode на консоли или в каком-либо текстовом файле. Таким образом, вы должны закодировать его (например, в UTF-8), вы вызываете кодирование ('utf-8') и вы получаете строку с '\ u' внутри, которая отлично печатается.

Затем, опять же - вы хотели бы сделать обратное - прочитать строку, закодированную в UTF-8, и обработать ее как Unicode, чтобы \u360 был одним символом, а не 5. Затем вы декодируете строку (с выбранной кодировкой) и получить новый объект типа Unicode.

Как примечание - вы можете выбрать некоторую извращенную кодировку, такую ​​как 'zip', 'base64', 'rot', и некоторые из них будут конвертировать из строки в строку, но я считаю, что наиболее распространенным случаем является тот, который включает UTF-8/UTF-16 и строка.

mybytestring.encode(somecodec) имеет смысл для этих значений somecodec:

  • base64
  • BZ2
  • Zlib
  • наговор
  • quopri
  • rot13
  • string_escape
  • уу

Я не уверен, для чего подходит декодирование уже декодированного текста Unicode. Попытка сделать это с любой кодировкой, кажется, всегда сначала пытается закодировать с использованием кодировки системы по умолчанию.

Вы должны прочитать Python UnicodeDecodeError - Я неправильно понимаю, закодировать. Мое понимание юникода в Python стало намного яснее после прочтения принятого ответа.

Существует несколько кодировок, которые можно использовать для дешифрования / кодирования из str в str или из unicode в unicode. Например, base64, hex или даже rot13. Они перечислены в модуле кодеков.

Редактировать:

Сообщение декодирования в строке Unicode может отменить соответствующую операцию кодирования:

In [1]: u'0a'.decode('hex')
Out[1]: '\n'

Возвращаемый тип - str вместо unicode, что, на мой взгляд, неудачно. Но когда вы не выполняете надлежащее декодирование / декодирование между str и unicode, это все равно выглядит как беспорядок.

Простой ответ заключается в том, что они являются полной противоположностью друг другу.

компьютер использует базовую единицу байта для хранения и обработки информации, это бессмысленно для человеческого глаза.

Например,'\xe4\xb8\xad\xe6\x96\x87' - это представление двух китайских символов, но компьютер знает (что означает печать или хранение), что это китайские иероглифы, когда им дают словарь для поиска этого Китайское слово, в данном случае это словарь "utf-8", и оно не сможет правильно отобразить намеченное китайское слово, если вы загляните в другой или неправильный словарь (используя другой метод декодирования).

В приведенном выше случае процесс поиска компьютером китайского слова - это decoding().

И процесс компьютерной записи китайцев в память компьютера кодируется ().

таким образом, информация о кодировании - это необработанные байты, а декодированная информация - это необработанные байты и имя словаря для ссылки (но не сам словарь).

Оба противоположны друг другу.

  1. Кодирование означает, что отправитель создает сообщение в определенном формате, чтобы получатель мог его прочитать.

например:

      import base64
def read_csv_file():
 with open( r'File_Path.csv', 'r') as fb:
   csv_read = csv.DictReader(fb)
   for row in csv_read:
     id = row["EMP_ID"].encode("ascii")
     x = base64.b64encode(bytes(id))      #encode
     print(x)
read_csv_file()
  1. Декодирование называется интерпретацией закодированного сообщения получателем.

    например:

    печать (base64.b64decode(b'SFExMTE='))

Другие вопросы по тегам