【问题标题】:How to open file using argparse?如何使用 argparse 打开文件?
【发布时间】:2013-09-22 15:47:51
【问题描述】:

我想使用 argparse 打开文件进行读取。 在 cmd 中它必须看起来像:my_program.py /filepath

这是我的尝试:

parser = argparse.ArgumentParser()
parser.add_argument('file', type = file)
args = parser.parse_args()

【问题讨论】:

  • 它到底做了什么?
  • 您目前有什么问题?
  • 运行这个我有错误:parser.add_argument('file', type = file) NameError: name 'file' is not defined 我不完全理解 argparse 是如何工作的......
  • type = fncfnc 是一个接受字符串并返回所需对象或引发错误的函数时有效。 Python 中没有 file 函数。 type=open 确实有效,因为有一个 Python 函数 open(filename)'. argparse provides a better function, argparse.FileType()`(实际上是一个函数构造函数)。但是wims 答案中的简单字符串参数是一个更好的起点。
  • type=file 在 Python2.7(及更早版本)中工作。但在 Python3 中,file 已被删除。 stackoverflow.com/questions/112970/…

标签: python argparse


【解决方案1】:

查看文档:https://docs.python.org/3/library/argparse.html#type

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('file', type=argparse.FileType('r'))
args = parser.parse_args()

print(args.file.readlines())

【讨论】:

  • @L0j1k 虽然我觉得这里有两个答案很好,但也应该提到argparse.FileType 的注意事项。例如,它使打开的文件句柄悬空,在我看来这是草率的实现。通常我宁愿自己处理文件open(),这样我就可以正确地处理它(使用上下文管理器),并自定义“找不到文件”错误的行为和输出。
  • 附注there is an issue on the python bug tracker about this,python 开发人员评论说“FileType 不是您想要的任何东西,而是可以让文件保持打开或关闭标准输入和/或标准输出的快速脚本”
  • 确实,这改变了一切。
  • 你可以做with args.file as f: ...,这将在好的情况下提前关闭文件。
  • @Wernight:但如果参数丢失或为-argparse 会自动将文件设置为<stdin>(或<stdout>,取决于mode)。这是一个非常酷的功能,但如果使用with args.file as f: ...,它会(或尝试)关闭它们,而它不应该这样做。
【解决方案2】:

参数的类型应该是字符串(无论如何都是默认的)。所以让它变成这样:

parser = argparse.ArgumentParser()
parser.add_argument('filename')
args = parser.parse_args()
with open(args.filename) as file:
  # do stuff here

【讨论】:

  • 请在 ilent2 的答案下查看 wim 的 cmets,了解为什么这个答案在大多数情况下可能是最佳答案。
  • 你不应该使用变量名file,因为这是一个内置的。
  • 一般来说这是正确的,但是 file 这些天从来没有在 python 中使用过——它在 python3 中被删除了,在 python2 中,文档字符串甚至建议使用 open 代替。所以踩这个名字就OK了,在核心库里甚至做了好几次。
【解决方案3】:

为了优雅地关闭文件,您可以将 argparse.FileType 与“with”语句结合使用

# ....

parser.add_argument('file', type=argparse.FileType('r'))
args = parser.parse_args()

with args.file as file:
    print file.read()

---更新---

哦,@Wernight 在 cmets 中已经说过了

【讨论】:

  • with args.file 行中的“文件”指的是参数的名称,对吗?如果我将参数命名为-f,那么它应该是with args.-f,对吗?如果我错了纠正我。 argparse 初学者在这里
  • @vishal.k 是也不是。如果你使用add_argument('-f', ...,那么你需要with args.f as file 没有破折号
  • 通过使用type=argparse.FileType('r'),文件将从您调用parser.parse_args() 的位置开始打开。这是否意味着如果您的代码在上下文处理程序之前崩溃,该文件仍将保持打开状态?没什么大不了的,但要记住一些事情。
【解决方案4】:

我将添加使用pathlib的选项:

import argparse, pathlib

parser = argparse.ArgumentParser()
parser.add_argument('file', type=pathlib.Path)
args = parser.parse_args()

with args.file.open('r') as file:
    print(file.read())

【讨论】:

    【解决方案5】:

    TL;博士

    parser.add_argument(
        '-f', '--file',
        help='JSON input file',
        type=argparse.FileType('r'),
    )
    

    说明

    用于重新格式化 JSON 文件的简单命令行脚本

    reformat-json \
        -f package.json \
        --indent=2 \
        --sort-keys \
        --output=sorted_package.json
    

    可以是Python中的代码如下

    #!/usr/bin/env python3
    
    import argparse, json, sys
    
    EXIT_SUCCESS = 0
    EXIT_FAILURE = 1
    
    def main():
        parser = argparse.ArgumentParser()
    
        parser.add_argument(
            '-f', '--file',
            help='JSON input file',
            type=argparse.FileType('r'),
        )
    
        parser.add_argument(
            '-i', '--indent',
            help='Non-negative integer indent level',
            type=int
        )
    
        parser.add_argument(
            '-o', '--output',
            help='Write JSON into output file',
            type=argparse.FileType('w'),
        )
    
        parser.add_argument(
            '-s', '--sort-keys',
            action='store_true',
            help='Sort output JSON by keys',
        )
    
        args = parser.parse_args()
    
        if not args.file:
            parser.print_usage()
            return sys.exit(EXIT_FAILURE)
    
        gson = json.dumps(
            json.load(args.file),
            indent=args.indent,
            sort_keys=args.sort_keys
        )
    
        args.file.close()
    
        if args.output:
            args.output.write(gson)
            args.output.write('\n')
            args.output.close()
        else:
            print(gson)
    
        return sys.exit(EXIT_SUCCESS)
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      【解决方案6】:

      此实现允许“文件名”参数是可选的,并在用户输入-h--help 参数时给出简短描述。

      parser = argparse.ArgumentParser(description='Foo is a program that does things')
      parser.add_argument('filename', nargs='?')
      args = parser.parse_args()
      
      if args.filename is not None:
          print('The file name is {}'.format(args.filename))
      else:
          print('Oh well ; No args, no problems')
      

      【讨论】:

      • 它根本没有回答这个问题。 OP 询问他们如何打开文件以使用 argparse 读取,而不是检查用户是否指定了文件名。
      猜你喜欢
      • 2020-10-14
      • 1970-01-01
      • 2021-12-23
      • 1970-01-01
      • 2010-10-05
      • 2012-07-20
      • 2019-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多