我有一个python脚本在我的本地机器(OS X)上运行良好,但是当我将它复制到服务器(Debian)时,它不能按预期工作。该脚本读取xml文件并以新格式打印内容。在我的本地机器上,我可以使用stdout将脚本运行到终端或文件(即> myFile.txt
),并且两者都可以正常工作。
但是,在服务器(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'
)。
如果我在shell中$ 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 :(得分: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://github.com/scrapy/scrapy/issues/1227
答案 1 :(得分:-1)
您可以在基于UnicodeError的异常的属性中找到与您遇到的错误相关的重要信息。
引用文档:
UnicodeError 具有描述编码或解码的属性 错误。例如,
err.object[err.start:err.end]
给出了特定的内容 编解码器失败的无效输入。<强>编码
引发错误的编码名称。
<强>原因强>
描述特定编解码器错误的字符串。
<强>对象强>
编解码器尝试编码或解码的对象。
开始强>
对象中无效数据的第一个索引。
<强>端强>
对象中最后一个无效数据之后的索引。