繁体   English   中英

Python中Perl(<>)的等价物是什么? fileinput无法按预期工作

[英]What is the equivalent of Perl's (<>) in Python? fileinput doesn't work as expected

在Perl中使用:

while (<>) {
    # process files given as command line arguments
}

在Python中我发现:

import fileinput
for line in fileinput.input():
    process(line)

但是,当命令行中给出的文件不存在时会发生什么?

python test.py test1.txt test2.txt filenotexist1.txt filenotexist2.txt test3.txt作为参数给出。

我尝试了各种使用try: except: nextfile ,但我似乎无法使其工作。

对于上面的命令行,脚本应该运行test1-3.txt但只是在test1-3.txt文件时转到下一个文件silent。

Perl非常好。 我在网上搜索过这个,但我无法在任何地方找到答案。

import sys
import os

for f in sys.argv[1:]:
    if os.path.exists(f):
        for line in open(f).readlines():
            process(line)

像这样的东西;

import sys

for f in sys.argv[1:]:
    try:
        data = open(f).readlines()
        process(data)
    except IOError:
        continue

将@Brian的答案转换为生成器,并捕获IOError而不是测试更多Pythonic的存在,然后在失败时向stderr发出警告:

import sys

def read_files(files = None):
  if not files:
    files = sys.argv[1:]
  for file in files:
    try:
      for line in open(file):
        yield line
    except IOError, e:
      print >>sys.stderr, 'Warning:', e

for line in read_files():
  print line,

输出(文件baz不存在):

$ python read_lines.py foo bar baz
line 1 of foo
line 2 of foo
line 1 of bar
line 2 of bar
Warning: [Errno 2] No such file or directory: 'baz'

您可能需要花一些精力来整理错误消息,但这可能不值得付出努力。

您可以使用fileinput模块解决您的问题,如下所示:

import fileinput

input = fileinput.input()
while True:
    try:
        process(input.next())
    except IOError:
        input.nextfile()
    except StopIteration:
        break

不幸的是你不能使用for循环,因为IOException打破了它。

我试图实施@ VGE的建议,但我的尝试结果并不太优雅。 我很感激有关如何改进这一点的任何建议。

import sys, fileinput, errno, os

class nosuchfile:
    def readlines(foo, bar):
        return []
    def close(arg):
        pass

EXITCODE=0

def skip_on_error (filename, mode):
    """Function to pass in as fileinput.input(openhook=...) hook function.
    Instead of give up on the first error, skip the rest of the file and
    continue with the next file in the input list.

    In case of an error from open() an error message is printed to standard
    error and the global variable EXITCODE gets overwritten by a nonzero
    value.
    """
    global EXITCODE
    try:
        return open(filename, mode)
    except IOError, e:
        sys.stderr.write ("%s: %s: %s\n" % (sys.argv[0], filename, os.strerror(e.errno)))
        EXITCODE = 1
        return nosuchfile()

def main ():
    do_stuff(fileinput.input(openhook=skip_on_error))
    return EXITCODE

占位符虚拟文件句柄类nosuchfile和全局变量EXITCODE都是非常严重的瑕疵。 我试图找出如何传入对本地范围的exitcode变量的引用,但放弃了。

这也无法处理读取时发生的错误,但大多数错误情况似乎都是在open发生的。

简单,明确和沉默:

import fileinput
from os.path import exists
import sys

for line in fileinput.input(files=filter(exists, sys.argv[1:])):
    process(line)

也许您可以使用openhook参数来控制不存在的文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM