这有点脆弱,因为它依赖于了解 argparse.ArgumentParser 的内部结构,但我使用以下代码代替重写 argparse.ArgumentParser.parse_known_args:
class OrderedNamespace(argparse.Namespace):
def __init__(self, **kwargs):
self.__dict__["_arg_order"] = []
self.__dict__["_arg_order_first_time_through"] = True
argparse.Namespace.__init__(self, **kwargs)
def __setattr__(self, name, value):
#print("Setting %s -> %s" % (name, value))
self.__dict__[name] = value
if name in self._arg_order and hasattr(self, "_arg_order_first_time_through"):
self.__dict__["_arg_order"] = []
delattr(self, "_arg_order_first_time_through")
self.__dict__["_arg_order"].append(name)
def _finalize(self):
if hasattr(self, "_arg_order_first_time_through"):
self.__dict__["_arg_order"] = []
delattr(self, "_arg_order_first_time_through")
def _latest_of(self, k1, k2):
try:
print self._arg_order
if self._arg_order.index(k1) > self._arg_order.index(k2):
return k1
except ValueError:
if k1 in self._arg_order:
return k1
return k2
一旦为每个参数设置默认值,argparse.ArgumentParser.parse_known_args 就会遍历整个选项列表。这意味着用户指定的参数在 __setattr__ 第一次遇到它以前见过的参数时开始。
用法:
options, extra_args = parser.parse_known_args(sys.argv, namespace=OrderedNamespace())
您可以检查options._arg_order 以获取用户指定的命令行参数的顺序,或者使用options._latest_of("arg1", "arg2") 来查看稍后在命令行中指定的--arg1 或--arg2 中的哪一个(我的目的是我需要:看看两个选项中的哪一个是最重要的)。
更新:必须添加_finalize 方法来处理sys.argv() 不包含列表中任何参数的病理情况)