Python:TypeError:'file'对象没有属性'__getitem__'

时间:2013-04-24 20:28:31

标签: python parsing exception typeerror gpx

我有一个.gpx文件,该文件在文件中间被截断。当我尝试使用gpxpy library解析它时,我遇到了以下错误。

Parsing points in track.gpx
ERROR:root:expected '>', line 3125, column 29
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gpxpy-0.8.7-py2.7.egg/gpxpy/parser.py", line 209, in parse
    self.xml_parser = LXMLParser(self.xml)
  File "/usr/local/lib/python2.7/dist-packages/gpxpy-0.8.7-py2.7.egg/gpxpy/parser.py", line 107, in __init__
    self.dom = mod_etree.XML(self.xml)
  File "lxml.etree.pyx", line 2734, in lxml.etree.XML (src/lxml/lxml.etree.c:54411)
  File "parser.pxi", line 1578, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:82748)
  File "parser.pxi", line 1457, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:81546)
  File "parser.pxi", line 965, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:78216)
  File "parser.pxi", line 569, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:74472)
  File "parser.pxi", line 650, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:75363)
  File "parser.pxi", line 590, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:74696)
XMLSyntaxError: expected '>', line 3125, column 29

File "gpxscript.py", line 370, in extractpoints gpx = gpxpy.parse(file)
File "/usr/local/lib/python2.7/dist-packages/gpxpy-0.8.7-py2.7.egg/gpxpy/__init__.py",
     line 28, in parse raise mod_gpx.GPXException('Error parsing {0}: {1}'
                       .format(xml_or_file[0 : 100], parser.get_error()))
TypeError: 'file' object has no attribute '__getitem__'

这些是产生错误的脚本的相关命令。

368  file = open(filepath)
369  try:
370      gpx = gpxpy.parse(file)
371  except gpxpy.gpx.GPXException:
372      print "GPXException for %s." % filepath
373      return 1

我按照建议提交了bug for the library。我在bug报告中添加了一个示例文件,产生语法错误。

1 个答案:

答案 0 :(得分:2)

这似乎是gpxpy错误处理中的错误。

查看parse的源代码,当解析器在没有引发异常的情况下失败时,它会尝试使用以下内容引发异常:

raise mod_gpx.GPXException('Error parsing {0}: {1}'.format(xml_or_file[0 : 100], parser.get_error()))

这假设xml_or_file是一个XML字符串 - 但顾名思义,它允许是字符串或文件对象。所以,你正在做什么(给它一个文件对象)是完全合法的,应该有效,但它没有,因此它是一个错误。

所以,你应该file an issue。正确的补丁应该是这样的:

if not parser.is_valid():
    try:
        fragment = xml_or_file[0 : 100]
    except TypeError:
        xml_or_file.seek(0)
        fragment = xml_or_file.read(100)
    raise mod_gpx.GPXException('Error parsing {0}: {1}'.format(fragment, parser.get_error()))

那么,你是如何解决这个问题的呢?一些选择:

  1. 因为无论如何只会出现无效文件,您只能使用except Exceptionexcept (gpxpy.gpx.GPXException, TypeError)

  2. 因为它只在你给它一个文件对象时发生,所以给它一个字符串代替:gpx = gpx.parse(file.read())。如果文件非常大,这是一个坏主意。当然。

  3. 由于buggy函数只包含12行简单的代码包装真实函数,所以直接使用实函数。或者,如果您喜欢包装器,请复制它,修复它,然后使用您自己的副本。


  4. 同时,鉴于我在这个库中看到的第一部分代码有一些明显的红色标记(为什么xml_or_file[0 : 100]而不仅仅是xml_or_file[:100]?为什么要捕获异常,扔掉它们然后设置一个标志,然后使用该标志来引发一个缺少所有信息的新异常?),如果你不能自己调试库,我不认为这个可以让你使用。