Юникод и байты

Введение

Примеры

  • 0

    основы

    В Python 3 str это тип с поддержкой Юникода строк, в то время как bytes типа для последовательностей необработанных байт.

     type("f") == type(u"f")  # True, <class 'str'>
    type(b"f")               # <class 'bytes'>
    
     

    В Python 2 случайная строка была последовательность необработанных байтов по умолчанию , а строка Юникода была каждая строка с «U» префиксом.

     type("f") == type(b"f")  # True, <type 'str'>
    type(u"f")               # <type 'unicode'>
     


    Юникод в байтах

    Строки Unicode могут быть преобразованы в байты с .encode(encoding) .

    Python 3

     >>> "£13.55".encode('utf8')
    b'\xc2\xa313.55'
    >>> "£13.55".encode('utf16')
    b'\xff\xfe\xa3\x001\x003\x00.\x005\x005\x00' 

    Python 2

    в PY2 кодирования консоли по умолчанию sys.getdefaultencoding() == 'ascii' , а не utf-8 , как и в PY3, поэтому его печати , как и в предыдущем примере, непосредственно не возможно.

     >>> print type(u"£13.55".encode('utf8'))
    <type 'str'>
    >>> print u"£13.55".encode('utf8')
    SyntaxError: Non-ASCII character '\xc2' in...
    
    # with encoding set inside a file
    
    # -*- coding: utf-8 -*-
    >>> print u"£13.55".encode('utf8')
    £13.55 


    Если кодирование не может справиться с строкой, UnicodeEncodeError поднимается:

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


    Байтов в юникод

    Б могут быть преобразованы в Юникоду строк с .decode(encoding) .

    Последовательность байтов может быть преобразована в строку Unicode только через соответствующую кодировку!

     >>> b'\xc2\xa313.55'.decode('utf8')
    '£13.55' 

    Если кодирование не может справиться с строкой, UnicodeDecodeError поднимается:

     >>> b'\xc2\xa313.55'.decode('utf16')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/csaftoiu/csaftoiu-github/yahoo-groups-backup/.virtualenv/bin/../lib/python3.5/encodings/utf_16.py", line 16, in decode
        return codecs.utf_16_decode(input, errors, True)
    UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x35 in position 6: truncated data 
  • 1

    Обработка ошибок кодирования / декодирования

    .encode и .decode оба имеют режимы ошибок.

    По умолчанию 'strict' , что вызывает исключения ошибки. Другие режимы более щадящие.

    кодирование

     >>> "£13.55".encode('ascii', errors='replace')
    b'?13.55'
    >>> "£13.55".encode('ascii', errors='ignore')
    b'13.55'
    >>> "£13.55".encode('ascii', errors='namereplace')
    b'\\N{POUND SIGN}13.55'
    >>> "£13.55".encode('ascii', errors='xmlcharrefreplace')
    b'£13.55'
    >>> "£13.55".encode('ascii', errors='backslashreplace')
    b'\\xa313.55' 

    расшифровка

     >>> b = "£13.55".encode('utf8')
    >>> b.decode('ascii', errors='replace')
    '��13.55'
    >>> b.decode('ascii', errors='ignore')
    '13.55'
    >>> b.decode('ascii', errors='backslashreplace')
    '\\xc2\\xa313.55' 

    боевой дух

    Из вышесказанного ясно, что при работе с юникодом и байтами важно сохранять правильность кодировки.

  • 1

    Файловый ввод / вывод

    Файлы открываются в недвоичном режиме (например , 'r' или 'w' ) сделки со строками. Кодирование является умолчанию используется именно 'utf8' .

     open(fn, mode='r')                    # opens file for reading in utf8
    open(fn, mode='r', encoding='utf16')  # opens file for reading utf16
    
    # ERROR: cannot write bytes when a string is expected:
    open("foo.txt", "w").write(b"foo")
    
     

    Файлы открываются в двоичном режиме (например , 'rb' или 'wb' ) сделки с байтами. Аргумент кодирования не может быть указан, поскольку кодировка отсутствует.

     open(fn, mode='wb')  # open file for writing bytes
    
    # ERROR: cannot write string when bytes is expected:
    open(fn, mode='wb').write("hi") 

Синтаксис

Параметры

Примечания