Python 如何使用argparse返回选项字符串?

Python 如何使用argparse返回选项字符串?,python,popen,argparse,Python,Popen,Argparse,现在是否可以从args获取字符串“--pattern”? 我需要这个字符串,这样我就可以构造一个cmd列表来传递给Popen,比如Popen(['some\u other\u program',args.pattern.option\u string,args.pattern],…)而不必重复它(并且必须在两个地方维护它)(Popen(['some\u other\u prog','--pattern',args.pattern],…)) 我需要为另一个程序创建一个包装器。一些arg需要传递给包

现在是否可以从
args
获取字符串
“--pattern”
? 我需要这个字符串,这样我就可以构造一个cmd列表来传递给Popen,比如
Popen(['some\u other\u program',args.pattern.option\u string,args.pattern],…)
而不必重复它(并且必须在两个地方维护它)(
Popen(['some\u other\u prog','--pattern',args.pattern],…)

我需要为另一个程序创建一个包装器。一些arg需要传递给包装程序(通过Popen),一些arg是包装器所必需的


有没有比下面的例子更好的方法

parser = argparse.ArgumentParser()
parser.add_argument("-p", "--pattern", help="Pattern file")
args = parser.parse_args()
这种将参数保存在变量中的方法不是很好,因为:

  • 将短期期权与长期期权一起维护变得很困难
  • Popen
    如果在另一个函数中调用,则需要将这些变量(或它们的dict)传递给该函数。这似乎是多余的,因为传递给它的
    args
    应该足够了

  • dest
    添加到
    Add_参数
    调用中

    pass_1 = '--to-be-passed'
    parser = argparse.ArgumentParser()
    parser.add_argument("-p", pass_1, help="Pass me on")
    parser.add_argument("-k", "--arg-for-wrapper")
    args = parser.parse_args()
    
    ...
    process = Popen(['wrapped_program', pass_1, args.pass_1], ...)
    ... 
    

    您可以使用
    args[“pattern”]

    引用模式。删除的答案和注释表明您对所需内容存在一些混淆。因此,我将增加这种混乱

    通常,解析器不会记录选项字符串。但是,它被提供给
    操作
    \u调用
    方法。因此,自定义操作类可以保存它。argparse文档中的
    FooAction
    自定义类示例说明了这一点

    如果我定义此操作子类:

    parser.add_argmument("p", "--pattern", dest="pattern", help="your help text")
    args = parser.parse_args()
    args = vars(args)
    
    选项字符串与值('-o'或'-other')一起记录:

    显然,选项_字符串和值可以以不同的顺序记录在字典中,作为名称空间中的独立属性,等等


    还有其他方法可以将选项传递给另一个程序,特别是在包装解析器不需要自己处理选项的情况下

    argparse
    sys.argv[1://code>获取参数,并且不更改它。因此,即使解析器使用了一些参数,也可以将该列表传递给
    popen
    (全部或部分)

    argparse docs在
    nargs=rements
    下有一个示例,它为自己解析一些参数,并收集其余参数以传递给另一个程序。这是他们的例子:

    In [322]: p.parse_args('-p test -o teseting'.split())
    Out[322]: Namespace(other=['teseting', '-o'], pass_me_on='test')
    
    In [323]: p.parse_args('-p test --other teseting'.split())
    Out[323]: Namespace(other=['teseting', '--other'], pass_me_on='test')
    
    因此,您可以使用以下命令调用
    popen

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('--foo')
    >>> parser.add_argument('command')
    >>> parser.add_argument('args', nargs=argparse.REMAINDER)
    >>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
    Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
    
    使用
    parse.parse_known_args
    还可以用于将未解析的单词收集到“extras”列表中。文档的这一部分讨论如何将这些字符串传递给另一个程序(就像您正在做的那样)。与剩余的情况相反,额外的东西不一定是最后一个

    当然,只有当解析器本身不需要
    --pattern
    时,这些功能才起作用。如果它解析了它,那么它就不会出现在余数或附加值中。在这种情况下,您必须将其添加回您提供的列表中
    popen

    我将对解析器进行如下调整:

    plist = ['wrapped_program']
    plist.extend(args.args)
    popen(plist, ...)
    
    另一种选择:

    pass_1 = 'passed'  # without the -- or internal -
    dpass_` = '--'+pass_
    parser = argparse.ArgumentParser()
    parser.add_argument("-p", dpass_1, help="Pass me on")
    parser.add_argument("-k", "--arg-for-wrapper")
    args = parser.parse_args()
    process = Popen(['wrapped_program', dpass_1, getattr(args, pass_1)], ...)
    
    如果打印
    pass\u action
    (在shell中),您将得到如下结果:

    parser = argparse.ArgumentParser()
    pass_action = parser.add_argument("-p", '--pass-me-on', help="Pass me on")
    parser.add_argument("-k", "--arg-for-wrapper")
    args = parser.parse_args()
    
    因此,您可以从该对象中提取
    --name
    dest
    ,因此:

     _StoreAction(option_strings=['-p', '--pass-me-on'], dest='pass_me_on', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
    
    您必须在
    sys.argv
    中查看所使用的选项字符串(长、短或其他)。解析器不会在任何地方记录这一点

    注释“--pass me on”产生
    dest='pass\u me\u on'
    。将
    -
    转换为
    -
    可能会使从一个字符串派生另一个字符串变得复杂

    如果您有一个
    dest
    字符串,则必须使用
    getattr
    将其从args命名空间中提取,或者使用
    vars(args)[dest]
    (字典访问)


    另一个问题。如果
    --patten
    具有
    nargs='+',则其值将是列表,而不是字符串。在将其合并到
    popen`参数列表中时,您必须小心。

    解析器的结果中获取原始选项字符串似乎不是一种简单的方法。parse_args()
    ,但您可以从
    解析器
    对象中获取它们。您只需查看它的
    \uuu dict\uuu
    ,就可以在创建
    解析器后检索它的设置。在您的情况下,您需要
    \u选项\u字符串\u操作
    字段。不幸的是,这似乎没有得到官方的支持,因为我找不到专门用于此的
    ArgumentParser
    方法,所以YMMV。在Python 3上:

    演示:


    为什么不把它存储在一个变量中呢
    pattern\u str='--pattern'
    ,然后
    。添加参数(…pattern\u str…)
    。这里-只有一个维护点。听起来像是你在试图硬编码两个独立程序之间的依赖关系(而且很死板:“这些程序必须共享选项名”)。这真的是你想要做的吗?@Hurkyl是的,python程序是另一个程序的包装器。同意@AmiTavory的解决方案是唯一一个可以按照你尝试的方式进行维护的解决方案。也许有一个全局dict,它将所有模式作为键,并将它们的选项标志作为值,同时还有大量的注释,说明为什么这些模式会被拉入global@AmiTavoryargparser解析两种类型的arg—python包装器特有的arg和要传递给Popen的arg。使用变量(用于将参数传递给Popen)而不是特定于包装器的变量似乎有点混乱,尽管这是一个更好的选择。我只是问是否有更好的方法。
    argparse
    --pattern
    推断dest是
    pattern
    。因此,不需要添加“dest”
    args
    是名称空间对象,而不是字典
    vars(args)
    从中生成字典。这并不能回答问题。他在问如何才能在一个地方定义,例如,
    --some opt
    ,但您没有说明如何将字符串
    --some opt
     _StoreAction(option_strings=['-p', '--pass-me-on'], dest='pass_me_on', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
    
    process = Popen(['wrapped_program', pass_action.option_strings[-1], getattr(args, pass_action.dest), ...], ...)
    
    parser = argparse.ArgumentParser()
    parser.add_argument('--foo', '-f', type=int, default=1000, help='intensity of bar')
    parser.add_argument('--bar', '-b', type=str, default='bla', help='whatever')
    store_action_dict=vars(parser)['_option_string_actions']
    print(store_action_dict.keys())    # dict_keys(['--help', '-b', '-f', '-h', '--foo', '--bar'])