2015-10-03 3 views
2

У меня есть сценарий python, который отлично работает на моей локальной машине (OS X), но когда я скопировал его на сервер (Debian), он не работает должным образом. Сценарий читает xml-файл и печатает содержимое в новом формате. На моей локальной машине я могу запустить скрипт с помощью stdout на терминал или в файл (т. Е. > myFile.txt), и оба работают нормально.UnicodeEncodeError при записи в файл

Однако, на сервере (ssh), когда я печатаю на терминал, все работает нормально, но печать в файл (что мне действительно нужно) дает UnicodeEncodeError: UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128). Все файлы находятся в кодировке utf-8, а utf-8 объявляется в волшебном комментарии.

Если я напечатаю объекты str внутри списка (это трюк, который я обычно использую для получения дескриптора при проблемах с кодировкой), он также выдает ту же ошибку.

Если я использую print(x.encode('utf-8')), тогда он печатает биты стиля кода (например, b'1' b'\xd0\x9a\xd0\xb0\xd0\xbc\xd0\xb0').

Если я $ export PYTHONIOENCODING=utf-8 в оболочке (как предложено в некоторых сообщениях SO), тогда я получаю двоичный файл: 1 <D0><9A><D0><B0><D0><BC><D0><B0>.

Я проверил все переменные locale, и соответствующие совпадают с тем, что у меня есть на моей локальной машине.

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

# -*- encoding: utf-8 -*- 
import sys, xml.etree.ElementTree as ET 

corpus = ET.parse('file.xml') 
text = corpus.getroot() 
for body in text : 
    for sent in body : 
    depDOMs = [(0,'') for i in range(len(sent)+1)] 
    for word in sent : 
     if word.tag == 'LF' : 
     pass 
     elif 'ID' in word.attrib and 'FEAT' in word.attrib and 'DOM' in word.attrib : 
     ID = word.attrib['ID'] 
     try : 
      Form = word.text.replace(' ','_') 
     except AttributeError : 
      Form = '_' 
     try : 
      Lemma = word.attrib['LEMMA'].replace(' ', '_') 
     except KeyError : 
      Lemma = '*NULL*' 
     CPOS = word.attrib['FEAT'].split()[0] 
     POS = word.attrib['FEAT'].replace(' ' , '_') 
     Feats = '_' 
     Head = word.attrib['DOM'] 
     if Head == '_root' : 
      Head = '0' 
     try : 
      DepRel = word.attrib['LINK'] 
     except KeyError : 
      DepRel = 'ROOT' 
     PHead = '_' 
     PDepRel = '_' 
     try: 
      if word.attrib['NODETYPE'] == 'FANTOM' : 
      word.attrib['LEMMA'] = '*'+word.attrib['LEMMA']+'*' 
     except KeyError : 
      pass 
     print(ID , Form , Lemma , Feats, CPOS , POS , Head , DepRel , PHead , PDepRel , sep='\t') 
     else : 
     print('WARNING: what is this?',sent.attrib['ID'],word.attrib) 
    print() 
+0

Просьба указать код, который вы используете –

+0

@AlastairMcCormack Code добавлен. Что касается редактирования вашего вопроса, откуда вы знаете, что это проблема исключительно python, а не bash/io? Почему вывод python зависит от адресата вывода? – reynoldsnlp

+0

Прохладный. Это происходит потому, что ошибка возникает, когда вы пишете файл, поэтому Bash не участвует (если вы не имеете в виду перенаправление). Тег ввода-вывода больше связан с физическим вводом-выводом –

ответ

2

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

Подтвердить настройку локали с помощью locale. Если есть проблема, вы увидите что-то вроде:

$ locale 
locale: Cannot set LC_CTYPE to default locale: No such file or directory 
locale: Cannot set LC_ALL to default locale: No such file or directory 
LANG=en_US.UTF-8 
LANGUAGE= 

исправить это с помощью:

$ sudo locale-gen "en_US.UTF-8" 

(заменить "en_US.UTF-8" с локалью, которая не работает). Для получения дополнительной информации см.: https://askubuntu.com/questions/162391/how-do-i-fix-my-locale-issue

-1

Вы можете найти важную информацию, связанную с ошибкой, которую вы испытываете в атрибутах Исключение на основе UnicodeError.

Цитируя документации:

UnicodeError has attributes that describe the encoding or decoding error. For example, err.object[err.start:err.end] gives the particular invalid input that the codec failed on.

encoding

The name of the encoding that raised the error.

reason

A string describing the specific codec error.

object

The object the codec was attempting to encode or decode.

start

The first index of invalid data in object.

end

The index after the last invalid data in object.

Смежные вопросы