【问题标题】:Encoding utf-8 error, when stdin is used instead of command line arguments当使用标准输入而不是命令行参数时,编码 utf-8 错误
【发布时间】:2014-02-20 16:00:11
【问题描述】:

我需要使我的脚本可用于 UNIX 命令,以便可以使用我的脚本一次处理 2 个输入文件。此脚本与命令行参数完美配合:

newlist = []
def f1()
 .... 
  return places 
  return persons
  return unknown

def f2(input_file):

  volume_id = sys.argv[3]   

  for line in input_data:  

     if any(place+'</dfn>' in line.decode('utf-8') for place in places):
         line = line.replace('"person"', '"place"')
         line = line.replace('id="', 'id="'+volume_id)
     elif any(unk+'</dfn>' in line.decode('utf-8') for unk in unknown):
         line = line.replace('"person"', '"undefined"')
         line = line.replace('id="', 'id="'+volume_id)
     elif 'class="person"' in line.decode('utf-8') and '<dfn' not in line:
         line = line.replace('class="person"', '')
         line = line.replace('id="', 'id="'+volume_id)
     elif 'id="' in line:
         line = line.replace('id="', 'id="'+volume_id)

     newlist.append(line)

  return  newlist                

def main():
   if len(sys.argv) < 4:
     print 'usage: ./myscript.py [file_in... file_out... volume_id]'
     sys.exit(1)

   else:

    filename = sys.argv[1]
    filename_out = sys.argv[2]

    tree = etree.parse(filename)
    extract(tree)

    input_file = open(filename, 'rU')
    change_class(input_file)

    file_new = open(filename_out, 'w')
    for x in newlist:

      if '\n' in x:                   
         x = x.replace('\n', '')                
      print>>file_new, x

当我尝试向它添加标准输入标准输出时,我首先遇到了先读取相同输入文件的问题,因此进行了一些更改,以便它实际上只打开一次。我修改了以下内容:

  def f2(input_data) #instead of input_file

我修改了 main():

        filename = sys.argv[1]
        filename_out = sys.argv[2]

        if filename == '-':
           input_file = sys.stdin

        else:
            input_file = open(filename, 'rU')


        if filename_out == '-':
            filename_out = sys.stdout
            file_new = filename_out
        else:
            file_new = open(filename_out, 'w')

        input_data = input_file.read()

        tree = etree.fromstring(input_data)
        extract(tree)


        change_class(input_data)

        for x in newlist:

            if '\n' in x:                   
               x = x.replace('\n', '')                
            print>>file_new, x

我从命令行运行程序: ./myscript.py --volumeid 输出文件

现在我遇到了编码问题:

Traceback (most recent call last):
  File "./exportXMLstd.py", line 192, in <module>
    main()
  File "./exportXMLstd.py", line 182, in main
    change_class(input_data)
  File "./exportXMLstd.py", line 135, in change_class
    if any(place+'</dfn>' in line.decode('utf-8') for place in places):
  File "./exportXMLstd.py", line 135, in <genexpr>
    if any(place+'</dfn>' in line.decode('utf-8') for place in places):
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe2 in position 0: unexpected end of data

我做错了什么?

【问题讨论】:

  • 你的缩进到处都是;能否请您使用复制和粘贴将您的代码放入问题中,然后在工具栏上的{} 按钮格式化代码,如果它还没有足够的缩进?
  • 我支持缩进注释。此外,您似乎假设 stdin 是 unicode - 在您的系统上是这样吗?实际上,如果您正在处理XML数据,最好还是假设utf-8,或者至少阅读xml声明语句并在那里解析编码?
  • 对不起,缩进很丑,我更正了。 @user590028,您是在说脚本开头的 # -- coding: utf-8 -- 吗?如果是这样,那我就有了。
  • @user590028,我不知道标准输入是否是 unicode,我可以在某处声明它吗?
  • 不...我指的是您正在执行的输入解码。我看到您正在打开文件 open(filename, 'rU')。这将返回 unicode 字符串...但是您没有尝试解码标准输入。我以为你认为标准输入会给你 unicode。我知道没有这样的系统——但这并不意味着你不在这样的系统上。我建议您打开文件 open(filename, 'rb'),并在每次读取后自己进行编码('utf-8')。

标签: python encoding stdout stdin


【解决方案1】:

这个怎么样:

if filename == '-':
    input_file = sys.stdin

else:
    input_file = open(filename, 'rb')

tree = etree.fromstring(input_file.read())
...

我认为 XML 源很可能是 utf-8(无论它来自标准输入还是来自文件)

【讨论】:

  • 现在我从 lxml 模块收到错误消息:lxml.etree.XMLSyntaxError: None
  • 调用 etree.fromstring() 时出现语法错误?如果你使用 python etree.fromstring (import xml.etree.ElementTree as etree) 会怎样
  • 但是我已经导入了 etree: from lxml import etree.无论如何,我尝试按照你说的导入 - 它产生另一个错误:xml.etree.ElementTree.ParseError: no element found: line 1, column 0
  • 实际上,lxml 和 xml.etree.ElementTree 都在源 XML 文档中报告语法错误。它是否包含 xml 声明语句?即:
  • 其实我的输入文件是html文件,它们直接以..etc开头,没有声明。但是我之前解析过它们,当我使用命令行参数时,没有任何问题
猜你喜欢
  • 2010-09-13
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 2015-09-03
  • 2010-12-11
  • 2011-01-31
相关资源
最近更新 更多