Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python将lxml与fileinput一起使用_Python_File Io_Lxml - Fatal编程技术网

Python将lxml与fileinput一起使用

Python将lxml与fileinput一起使用,python,file-io,lxml,Python,File Io,Lxml,拥有一个简单的xml <?xml version="1.0" encoding="UTF-8" ?> <root> <child>abc</child> </root> 然而,我尝试修改脚本,然后允许它从文件或stdin解析xml,但没有成功: fi = fileinput.input('tst.xml') for _, element in lxml.etree.iterparse(fi, tag='child'):

拥有一个简单的xml

<?xml version="1.0" encoding="UTF-8" ?>
<root>
    <child>abc</child>
</root>
然而,我尝试修改脚本,然后允许它从文件或
stdin
解析xml,但没有成功:

fi = fileinput.input('tst.xml')
for _, element in lxml.etree.iterparse(fi, tag='child'):
    print element.text

# File "iterparse.pxi", line 371, in lxml.etree.iterparse.__init__ (src/lxml/lxml.etree.c:97283)
# File "apihelpers.pxi", line 1411, in lxml.etree._encodeFilename (src/lxml/lxml.etree.c:22515)
# TypeError: Argument must be string or unicode.

我不确定我做错了什么。对象在python中不是类似文件的对象吗?

您不应该尝试使用
fileinput
模块,而是直接这样做:

if filename == '-':   # or, if we don't have a filename argument
    f = sys.stdin
else:
    f = open(filename, 'r')

在没有深入调查的情况下,出现异常的原因似乎是
FileInput
类没有提供
read
方法。 为了实现我的目标,我现在开始写我自己的包装:

class FileInput(object):
    def __init__(self, filename=None, *args, **kwargs):
        self.file = open(filename, *args, **kwargs) if filename and filename != "-" else sys.stdin

    def __enter__(self):
        return self.file

    def __exit__(self, type, value, traceback):
        if self.file is not sys.stdin:
            self.file.close()

    def __getattr__(self, name):
        return getattr(self.file, name)

不过我会等待一个更好的答案。

也许
lxml.etree.iterparse()
只处理一个真实的文件,而不是任何类似文件的对象。这可能不是真的,因为
sys.stdin
据说是一个类似文件的对象,在Python 2.x中,
iterparse()
解析时没有任何问题,默认情况下,
sys.stdin
是一个真正的文件对象——我的意思是它的
type()
file
fileinput.input()的情况并非如此。请注意,后者有一个方法
fileno()
,但它返回-1。我不确定使用返回-1的方法
fileno()
的意义何在,因为任何C代码试图通过查询其文件描述符来使用类似文件的对象,都会在尝试使用-1时出错…但是。。为什么?您的方法没有提供正确的结束处理。如果f不是sys.stdin:f.close()
,而且它也不是异常安全的,那么我必须编写样板文件
。您使用
文件输入
也不能提供正确的关闭处理。。。事实上,
fileinput
是一个非常古老的Python模块,因此它不能与
with
语句结合使用。使用
试试:最后:
怎么样?我同意这只是几行样板文件,但我不知道还有什么更简洁的解决方案,对不起。我尽可能简化了我的示例,它看起来像是
以contextlib.closing(fileinput.input(args.input))作为输入:
在现实世界中,它提供了必要的异常安全性,并且工作正常,因为
FileInput
close()
方法检查了
sys.stdin
而没有关闭它。无论如何,谢谢你的帮助。
class FileInput(object):
    def __init__(self, filename=None, *args, **kwargs):
        self.file = open(filename, *args, **kwargs) if filename and filename != "-" else sys.stdin

    def __enter__(self):
        return self.file

    def __exit__(self, type, value, traceback):
        if self.file is not sys.stdin:
            self.file.close()

    def __getattr__(self, name):
        return getattr(self.file, name)