Python: конвертировать китайские иероглифы в пиньинь с помощью CJKLIB - PullRequest
2 голосов
/ 28 августа 2011

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

Вот код,

from cjklib.characterlookup import CharacterLookup

source_file = 'cities_test.txt'
dest_file = 'output.txt'

s = open(source_file, 'r')
d = open(dest_file, 'w')

cjk = CharacterLookup('T')

for line in s:
    p = line.split('\t')
    for p_shard in p:
        for c in p_shard:
            readings = cjk.getReadingForCharacter(c.encode('utf-8'), 'Pinyin')
            d.write(readings[0].encode('utf-8'))
        d.write('\t')
    d.write('\n')

s.close()
d.close()

Моя проблема заключается в том, что я продолжаю сталкиваться с ошибками, связанными с Unicode, ошибка возникает при вызове функции getReadingForCharacter. Если бы я назвал это так, как написано,

readings = cjk.getReadingForCharacter(c.encode('utf-8'), 'Pinyin')

Я получаю: UnicodeDecodeError: кодек «ascii» не может декодировать байт 0xef в позиции 0: порядковый номер не в диапазоне (128).

Если я назову это так, без .encoding(),

readings = cjk.getReadingForCharacter(c, 'Pinyin')

Я получаю сообщение об ошибке, выдаваемое sqlalchemy (CJKLIB использует sqlalchemy и sqlite): вы не должны использовать 8-битные строки байтов, если вы не используете text_factory, который может интерпретировать 8-битные строки байтов ... и т. Д.

Может ли кто-нибудь мне помочь? Спасибо!

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

1 Ответ

1 голос
/ 28 августа 2011

Ваша ошибка в том, что вы не декодируете входной поток, и все же вы поворачиваетесь и перекодируете , как если бы это был UTF-8. Это идет не в ту сторону.

У вас есть два варианта.

Вы можете codecs.open входной файл с явной кодировкой, чтобы вы всегда возвращали обычные строки Unicode всякий раз, когда читаете из него, потому что декодирование происходит автоматически. Это всегда мое сильное предпочтение. Текстового файла больше не существует.

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

Я бы сделал то же самое для выходного файла. Я просто ненавижу видеть вручную .encode("utf-8") и .decode("utf-8") повсюду. Установите кодировку потока и покончите с этим.

...