加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

为什么Python argparse中的fromfile-prefix-chars不起作用?

发布时间:2020-12-20 11:36:59 所属栏目:Python 来源:网络整理
导读:我试图在 Python中使用argparse的fromfile-prefix-chars功能从文件加载我的所有命令行参数,但它一直在抱怨我没有指定一些参数. 代码: import argparsedef go(): parser = argparse.ArgumentParser(fromfile_prefix_chars='@') parser.add_argument("--optio
我试图在 Python中使用argparse的fromfile-prefix-chars功能从文件加载我的所有命令行参数,但它一直在抱怨我没有指定一些参数.

代码:

import argparse

def go():
   parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
   parser.add_argument("--option1")
   parser.add_argument("--option2",type=int,required=True)
   args = parser.parse_args()

if __name__ == "__main__":
    go()

参数文件:

--option1 foo
--option2 1234

命令行和输出:

$python testargparse.py @testargs
usage: testargparse.py [-h] [--option1 OPTION1] --option2 OPTION2
testargparse.py: error: argument --option2 is required

你可以看到我在文件中提供了必需的参数,但是argparse没有看到它.

解决方法

从文档:

Arguments read from a file must by default be one per line … and are treated as if they were in the same place as the original file referencing argument on the command line. So in the example above,the expression [‘-f’,‘foo’,‘@args.txt’] is considered equivalent to the expression [‘-f’,‘-f’,‘bar’].

在示例中:

fp.write('-fnbar')

所以该文件包含:

-f
bar

换句话说,每个文件行对应于命令行中的一个“字”(空白分隔). –option1 = foo是一个单词. –option1 foo被解释为就像在命令行中引用一样,例如. prog.py’ – option1 foo” – option2 1234′

https://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser.convert_arg_line_to_args有一个自定义功能,可以在空格上分割线条.如果你想坚持参数文件,试验一下.

import argparse

with open('args.txt','w') as fp:
    fp.write('--option1 foon--option2 1234')  # error
    # but works with modifed 'convert...'
    #fp.write('--option1=foon--option2=1234')  # works
    #fp.write('--option1nfoon--option2n1234') # works

def convert_arg_line_to_args(arg_line):
    for arg in arg_line.split():
        if not arg.strip():
            continue
        yield arg
"""
default line converter:
def convert_arg_line_to_args(self,arg_line):
    return [arg_line]
"""

def go():
   parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
   parser.convert_arg_line_to_args = convert_arg_line_to_args
   parser.add_argument("--option1")
   parser.add_argument("--option2",required=True)
   args = parser.parse_args(['@args.txt'])
   print args

if __name__ == "__main__":
    go()

@toes建议使用shlex来解析文件. shlex有一个很好的功能,它会删除不必要的引号.

shlex可用于拆分文件的各行.

def sh_split(arg_line):
    for arg in shlex.split(arg_line):
        yield arg
parser.convert_arg_line_to_args = sh_split

或者它可以替换整个@file读取方法(_read_args_from_files) – 这应该与@toes应答相同,除了@file字符串可以在命令行中的任何位置(甚至可以重复).

def at_read_fn(arg_strings):
    # expand arguments referencing files
    new_arg_strings = []
    for arg_string in arg_strings:
        if not arg_string or not arg_string.startswith('@'):
            new_arg_strings.append(arg_string)
        else:
            with open(arg_string[1:]) as args_file:
                arg_strings = shlex.split(args_file.read())
                new_arg_strings.extend(arg_strings)
    return new_arg_strings
parser._read_args_from_files = at_read_fn

显然,更清洁的生产版本会在ArgumentParser子类中修改这些方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读