如何访问 argparse 键名而不是值?
How to access argparse key name instead of value?
A callee.py
有这个 Namespace
使用它的 argparse
:
parser = Namespace(action='run', action_area='park', severity='high')
In [30]: parser.action
Out[30]: 'run'
如果你在命令行中输入,这应该足够了:
callee.py --run --action_area gym --severity low
如果调用在另一个程序中 caller.py
,我想这样做:
callee.py sth.run sth.action_area 'gym' sth.severity 'low'
优点是:
更规范
如果 callee.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'
我的问题是:在 argparse
中是否有某种方式或其他方式我不必为此构建 class?
这只是一个解释要求的例子,如果功能不可用(我认为应该),如何实现这个不限于argparse
。
我确定我不是第一个也是最后一个需要此功能的人。希望这次能解释清楚。
通常使用argparse
的方法是定义一个解析器,填充它的'arguments',然后调用parse_args()
来解析命令行。
parse_args()
returns 您随后使用的命名空间对象。
可以直接定义命名空间对象:
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])
您可以向现有对象添加值,但不能访问未定义的值。 Namespace
class 很简单,只是增加了一些方法让数值显示更漂亮。
您还可以从中获取字典:
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']
正在使用 key
字符串获取值:
In [212]: getattr(ns,'x')
Out[212]: 12
您还可以通过名称设置属性
In [220]: setattr(ns,'w','other')
In [221]: ns
Out[221]: Namespace(w='other', x=12, y='abc', z=[1, 2, 3])
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())
self.__dict__
与 vars(ns)
相同。属性存储在这个字典中(大多数对象都是如此,尤其是用户定义的对象)。
如果您想使用 Namespace
做更多事情,或者定义您自己的 class,我建议您查看 argparse.py
文件中的 class。 argparse
试图对这个 class 的性质做出最少的假设。在可能的情况下,它使用 getattr
和 setattr
函数。还有 hasattr
:
In [222]: hasattr(ns, 'foo')
Out[222]: False
In [223]: hasattr(ns, 'w')
Out[223]: True
从您的编辑来看,您似乎想要 'recover' 命名空间中属性名称的选项标志。即
parser.add_argument('--foo', '-f', ...)
parser.add_argument('bar', ...)
parser.add_argument('--other', dest='baz',...)
会产生一个Namespace(foo=..., bar=....)
属性名叫做dest
。那是在保存值时解析器使用
setattr(namespace, dest, value)
对于位置参数,dest
是第一个参数,在上例中是 'bar'。对于可选参数,dest
派生自第一个长参数,即上面的“--foo”。或者可以使用显式 dest='baz'
参数进行设置。
所以只需在 ns.__dict__
键上添加一个 --
就可以开始了。
argparse
中没有任何代码可以根据解析结果重新创建命令行。
A callee.py
有这个 Namespace
使用它的 argparse
:
parser = Namespace(action='run', action_area='park', severity='high')
In [30]: parser.action
Out[30]: 'run'
如果你在命令行中输入,这应该足够了:
callee.py --run --action_area gym --severity low
如果调用在另一个程序中 caller.py
,我想这样做:
callee.py sth.run sth.action_area 'gym' sth.severity 'low'
优点是:
更规范
如果 callee.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'
我的问题是:在 argparse
中是否有某种方式或其他方式我不必为此构建 class?
这只是一个解释要求的例子,如果功能不可用(我认为应该),如何实现这个不限于argparse
。
我确定我不是第一个也是最后一个需要此功能的人。希望这次能解释清楚。
通常使用argparse
的方法是定义一个解析器,填充它的'arguments',然后调用parse_args()
来解析命令行。
parse_args()
returns 您随后使用的命名空间对象。
可以直接定义命名空间对象:
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])
您可以向现有对象添加值,但不能访问未定义的值。 Namespace
class 很简单,只是增加了一些方法让数值显示更漂亮。
您还可以从中获取字典:
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']
正在使用 key
字符串获取值:
In [212]: getattr(ns,'x')
Out[212]: 12
您还可以通过名称设置属性
In [220]: setattr(ns,'w','other')
In [221]: ns
Out[221]: Namespace(w='other', x=12, y='abc', z=[1, 2, 3])
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())
self.__dict__
与 vars(ns)
相同。属性存储在这个字典中(大多数对象都是如此,尤其是用户定义的对象)。
如果您想使用 Namespace
做更多事情,或者定义您自己的 class,我建议您查看 argparse.py
文件中的 class。 argparse
试图对这个 class 的性质做出最少的假设。在可能的情况下,它使用 getattr
和 setattr
函数。还有 hasattr
:
In [222]: hasattr(ns, 'foo')
Out[222]: False
In [223]: hasattr(ns, 'w')
Out[223]: True
从您的编辑来看,您似乎想要 'recover' 命名空间中属性名称的选项标志。即
parser.add_argument('--foo', '-f', ...)
parser.add_argument('bar', ...)
parser.add_argument('--other', dest='baz',...)
会产生一个Namespace(foo=..., bar=....)
属性名叫做dest
。那是在保存值时解析器使用
setattr(namespace, dest, value)
对于位置参数,dest
是第一个参数,在上例中是 'bar'。对于可选参数,dest
派生自第一个长参数,即上面的“--foo”。或者可以使用显式 dest='baz'
参数进行设置。
所以只需在 ns.__dict__
键上添加一个 --
就可以开始了。
argparse
中没有任何代码可以根据解析结果重新创建命令行。