Каков наилучший способ определения метода декодирования строки Unicode в Python - PullRequest
4 голосов
/ 26 января 2012

Мне было интересно, как определить кодировку юникода.

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

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

Честно говоря, я хотел бы превратить его в unicode utf-8, не путая символыпрежде чем работать с ним.

Т.е.:

latin1_unicode = 'åäö'.decode('latin-1')
utf8_unicode = latin.encode('latin-1').decode('utf-8')

1 Ответ

1 голос
/ 26 января 2012

Если в «определить кодировку юникода» «unicode» является типом данных python, то вы не можете это сделать, поскольку «кодировка» относится к исходным шаблонам байтов, которые представляли строку при вводе (скажем,, читать из файла, базы данных, вы называете это).К тому времени, когда она становится типом «Юникод» Python (внутренним представлением), строка либо была декодирована за строкой, либо вызвала исключение декодирования, поскольку последовательность байтов не соответствовала кодировке системы.

Ответ Шадьябхи относится к (общему) случаю, когда вы читаете байты из файла (который вы могли бы очень хорошо вставить в строку - не в строку Python Unicode) инужно угадать в какой кодировке они были сохранены.Строго говоря, вы не можете иметь «латинскую строку Python Unicode»: строка Python Unicode не имеет кодирования (кодирование может быть определено как процесс, который переводит символ в байтовый шаблон, а декодирование - как обратный процесс; декодированная строка не имеет поэтомукодирование - хотя оно может быть закодировано несколькими способами для целей хранения / внешнего представления).

Например, на моей машине:

In [35]: sys.stdin.encoding
Out[35]: 'UTF-8'

In [36]: a='è'.decode('UTF-8')

In [37]: b='è'.decode('latin-1')

In [38]: a
Out[38]: u'\xe8'

In [39]: b
Out[39]: u'\xc3\xa8'
In [41]: sys.stdout.encoding
Out[41]: 'UTF-8'

In [42]: print b #it's garbage
è

In [43]: print a #it's OK
è

Это означает, что в вашем примере latin1_unicode будет содержатьмусор, если кодировкой по умолчанию является UTF-8, или UTF-16, или что-то отличное от latin1.

Итак, что вы (возможно) хотите сделать:

  1. Определите кодировку вашего источника данных - возможно, используя один из методов Шадьябхи
  2. Декодируйте данные в соответствии с (1), сохраните их в строки Unicode Python
  3. Кодируйте их, используя оригинальную кодировку (если эточто соответствует вашим потребностям) или другую кодировку по вашему выбору.
...