argparse:乱序处理某些参数

如何解决argparse:乱序处理某些参数

我有一个 python 应用程序,它有一些可重复的参数,交错顺序很重要。例如app -f 1 -b 2 -f 3app -f 1 -f 3 -b 2 不是同一个命令。

问题是我也有详细控制参数,我希望它影响在操作中执行的代码的日志记录行为。

有没有办法让 argparse 乱序处理某些参数,以便在处理其他参数之前应用详细控制,而不管它出现在 argv 中的什么位置?

# test.py
import argparse
import logging

def foo(x):
  logging.info(f'hi foo {x}')

def bar(x):
  logging.debug(f'hi bar {x}')

def SetVerbosity(log_level):
    class Action(argparse.Action):
        def __call__(self,parser,namespace,values,option_string=None):
            logging.getLogger(values).setLevel(level=log_level)

    return Action

class PerformFoo(argparse.Action):
    def __call__(self,option_string=None):
        foo(values)

class PerformBar(argparse.Action):
    def __call__(self,option_string=None):
        bar(values)

parser = argparse.ArgumentParser()

parser.add_argument('-v','--verbose',nargs='?',action=SetVerbosity(logging.INFO))
parser.add_argument('-vv',action=SetVerbosity(logging.DEBUG))

parser.add_argument('-f','--foo',Metavar='VAL',action=PerformFoo,help='Do a foo')
parser.add_argument('-b','--bar',action=PerformBar,help='Do a bar')

logging.basicConfig()
parser.parse_args()
# No problem
python test.py -v -f 1 -b 2 -f 3
INFO:root:hi foo 1
INFO:root:hi foo 3

# kind of unfortunate
app -f 1 -b 2 -f 3 -v
*crickets*

作为后备,我知道我可以将 -f-b 累积在一个异类的“待办事项”列表中,并在事后处理它们。但是,如果有一种相当简单的方法解决这个问题,而无需额外的间接层,我宁愿不跳过那个额外的环节。

解决方法

看到选项时不要调用 foovar。相反,在解析所有选项后收集要执行的操作列表。

类似的东西

import argparse
import logging

def foo(x):
  pass

def bar(x):
  pass

def SetVerbosity(value):
    class Action(argparse.Action):
        def __call__(self,parser,namespace,values,option_string=None):
            logging.getLogger(values).setLevel(level=value)

    return Action

class PerformFoo(argparse.Action):
    def __call__(self,option_string=None):
        namespace.to_do += [(foo,values)]

class PerformBar(argparse.Action):
    def __call__(self,option_string=None):
        namespace.to_do += [(bar,values)]

parser = argparse.ArgumentParser()

parser.add_argument('-v','--verbose',nargs='?',action=SetVerbosity(logging.INFO))
parser.add_argument('-vv',action=SetVerbosity(logging.DEBUG))

parser.add_argument('-f','--foo',metavar='VAL',action=PerformFoo,help='Do a foo')
parser.add_argument('-b','--bar',action=PerformBar,help='Do a bar')

args = parser.parse_args()

for f,v in args.to_do:
    f(v)
,

按照历史悠久的传统,我在发布问题后不久就设法找到了答案。

如果其他人在这里登陆,我设法通过创建第二个解析器并使用 parse_known_args() 调用它来实现,以便忽略非详细参数。

verbosityParser = argparse.ArgumentParser(add_help=False)
parser = argparse.ArgumentParser()

verbosityParser.add_argument('-v',action=SetVerbosity(logging.INFO))
verbosityParser.add_argument('-vv',action=SetVerbosity(logging.DEBUG))

# Still add verbosity to the "main" parser so that it shows up in help
parser.add_argument('-v',nargs='?')
parser.add_argument('-vv',nargs='?')
parser.add_argument('-f',help='Do a bar')

logging.basicConfig()
verbosityParser.parse_known_args()
parser.parse_args()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?