В чем разница между кодированием / декодированием?
Я никогда не был уверен, что понимаю разницу между декодированием 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().
И процесс компьютерной записи китайцев в память компьютера кодируется ().
таким образом, информация о кодировании - это необработанные байты, а декодированная информация - это необработанные байты и имя словаря для ссылки (но не сам словарь).
Оба противоположны друг другу.
- Кодирование означает, что отправитель создает сообщение в определенном формате, чтобы получатель мог его прочитать.
например:
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()
Декодирование называется интерпретацией закодированного сообщения получателем.
например:
печать (base64.b64decode(b'SFExMTE='))