如何访问 argparse 键名而不是值?

Gan*_*ang -1 python argparse

Acallee.py有这个Namespace使用它的argparse

parser = Namespace(action='run', action_area='park', severity='high')

In [30]: parser.action
Out[30]: 'run'
Run Code Online (Sandbox Code Playgroud)

如果你在命令行中输入,这应该足够了:

callee.py --run --action_area gym --severity low
Run Code Online (Sandbox Code Playgroud)

如果调用在另一个程序中caller.py,我想这样做:

callee.py sth.run sth.action_area 'gym' sth.severity 'low'
Run Code Online (Sandbox Code Playgroud)

优点是:更规范更容易更新如果 argscallee.py发生变化

我希望sth来自argparse或我不必自己编码的东西。

我可以这样构建sth

class ParserKeys(object):
    def __init__(self, keys):
        self.keys = keys
        for key in keys:
            setattr(self, key, '--{0}'.format(key))

sth = ParserKeys(vars(parser).keys())

In [91]: sth.action
Out[91]: '--action'
Run Code Online (Sandbox Code Playgroud)

我的问题是:有没有一种argparse方法可以让我不必为此构建一个类?

这只是一个解释要求的例子,如何实现这一点不限于argparse如果功能不可用(我认为应该)。

我确信我不是第一个也是最后一个需要此功能的人。我希望这次我解释清楚。

hpa*_*ulj 6

通常使用的方法argparse是定义一个解析器,填充它的“参数”,然后调用parse_args()来解析命令行。

parse_args() 返回一个 Namespace 对象,然后您可以使用它。

可以直接定义 Namespace 对象:

In [203]: ns = argparse.Namespace(x=12, y='abc')
In [204]: ns
Out[204]: Namespace(x=12, y='abc')
In [205]: ns.x
Out[205]: 12
In [207]: ns.z = [1,2,3]
In [208]: ns
Out[208]: Namespace(x=12, y='abc', z=[1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

您可以向现有对象添加值,但不能访问未定义的值。这个Namespace类很简单,只是添加了一些方法来使值的显示更漂亮。

您还可以从中获取字典:

In [209]: vars(ns)
Out[209]: {'x': 12, 'y': 'abc', 'z': [1, 2, 3]}

In [210]: list(vars(ns).keys())
Out[210]: ['z', 'y', 'x']
Run Code Online (Sandbox Code Playgroud)

使用key字符串获取值:

In [212]: getattr(ns,'x')
Out[212]: 12
Run Code Online (Sandbox Code Playgroud)

您还可以按名称设置属性

In [220]: setattr(ns,'w','other')
In [221]: ns
Out[221]: Namespace(w='other', x=12, y='abc', z=[1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

该方法ns用来显示其值是:

def __repr__(self):
    type_name = type(self).__name__
    arg_strings = []
    for arg in self._get_args():
        arg_strings.append(repr(arg))
    for name, value in self._get_kwargs():
        arg_strings.append('%s=%r' % (name, value))
    return '%s(%s)' % (type_name, ', '.join(arg_strings))

def _get_kwargs(self):
    return sorted(self.__dict__.items())
Run Code Online (Sandbox Code Playgroud)

self.__dict__是一样的东西vars(ns)给。属性存储在此字典中(对于大多数对象,尤其是用户定义的对象都是如此)。

如果你想用 做更多的事情Namespace,或者定义你自己的类,我建议你查看argparse.py文件中的类。 argparse试图对这个类的性质做最少的假设。在可能的情况下,它使用getattrsetattr函数。而且hasattr还有:

In [222]: hasattr(ns, 'foo')
Out[222]: False
In [223]: hasattr(ns, 'w')
Out[223]: True
Run Code Online (Sandbox Code Playgroud)

从您的编辑中,听起来您想从命名空间中的属性名称中“恢复”选项标志。那是

 parser.add_argument('--foo', '-f', ...)
 parser.add_argument('bar', ...)
 parser.add_argument('--other', dest='baz',...)
Run Code Online (Sandbox Code Playgroud)

会产生一个 Namespace(foo=..., bar=....)

属性名称称为dest. 那是在保存解析器使用的值时

 setattr(namespace, dest, value)
Run Code Online (Sandbox Code Playgroud)

对于位置参数,dest上例中的第一个参数是“bar”。对于可选参数,dest派生自第一个长参数,即上面的“--foo”。或者它可以使用显式dest='baz'参数设置。

因此,只需--ns.__dict__键上添加 a即可开始。

没有任何代码argparse可以根据解析结果重新创建命令行。