写入文件

时间:2015-10-03 15:16:55

标签: python linux character-encoding locale

我有一个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()

2 个答案:

答案 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]给出了特定的内容   编解码器失败的无效输入。

     

<强>编码

     

引发错误的编码名称。

     

<强>原因

     

描述特定编解码器错误的字符串。

     

<强>对象

     

编解码器尝试编码或解码的对象。

     

开始

     

对象中无效数据的第一个索引。

     

<强>端

     

对象中最后一个无效数据之后的索引。