Omn*_*ous 33 python argparse python-3.x
我正在写一个程序,我希望有这样的参数:
--[no-]foo Do (or do not) foo. Default is do.
Run Code Online (Sandbox Code Playgroud)
有没有办法让argparse为我这样做?
我正在使用Python 3.2
Omn*_*ous 22
那么,到目前为止,由于各种原因,所有答案都不能令人满意.所以这是我自己的答案:
class ActionNoYes(argparse.Action):
def __init__(self, opt_name, dest, default=True, required=False, help=None):
super(ActionNoYes, self).__init__(['--' + opt_name, '--no-' + opt_name], dest, nargs=0, const=None, default=default, required=required, help=help)
def __call__(self, parser, namespace, values, option_string=None):
if option_string.starts_with('--no-'):
setattr(namespace, self.dest, False)
else:
setattr(namespace, self.dest, True)
Run Code Online (Sandbox Code Playgroud)
以及使用示例:
>>> p = argparse.ArgumentParser()
>>> p._add_action(ActionNoYes('foo', 'foo', help="Do (or do not) foo. (default do)"))
ActionNoYes(option_strings=['--foo', '--no-foo'], dest='foo', nargs=0, const=None, default=True, type=None, choices=None, help='Do (or do not) foo. (default do)', metavar=None)
>>> p.parse_args(['--no-foo', '--foo', '--no-foo'])
Namespace(foo=False)
>>> p.print_help()
usage: -c [-h] [--foo]
optional arguments:
-h, --help show this help message and exit
--foo, --no-foo Do (or do not) foo. (default do)
Run Code Online (Sandbox Code Playgroud)
遗憾的是,_add_action
成员函数没有记录,因此在API支持方面,这不是"官方".另外,Action
主要是持有者类.它本身的行为很少.如果可以使用它来更新自定义帮助消息,那将是很好的.例如--[no-]foo
,在开头说.但是那部分是由课外的东西自动生成的Action
.
hpa*_*ulj 17
v3.9 添加了一个action
类来执行此操作。来自文档(靠近本节末尾action
)
可用
BooleanOptionalAction
并argparse
添加了对布尔操作的支持,例如--foo
和--no-foo
:Run Code Online (Sandbox Code Playgroud)>>> import argparse >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action=argparse.BooleanOptionalAction) >>> parser.parse_args(['--no-foo']) Namespace(foo=False)
探索@wim 关于不相互排斥的评论。
In [37]: >>> parser = argparse.ArgumentParser()
...: >>> parser.add_argument('--foo', action=argparse.BooleanOptionalAction)
Out[37]: BooleanOptionalAction(option_strings=['--foo', '--no-foo'], dest='foo', nargs=0, const=None, default=None, type=None, choices=None, help=None, metavar=None)
Run Code Online (Sandbox Code Playgroud)
最后一行显示创建add_argument
了一个BooleanOptionalAction
Action 类。
具有各种输入:
In [38]: parser.parse_args('--foo'.split())
Out[38]: Namespace(foo=True)
In [39]: parser.parse_args('--no-foo'.split())
Out[39]: Namespace(foo=False)
In [40]: parser.parse_args([])
Out[40]: Namespace(foo=None)
In [41]: parser.parse_args('--no-foo --foo'.split())
Out[41]: Namespace(foo=True)
Run Code Online (Sandbox Code Playgroud)
因此,您可以提供两个标志,最后一个标志生效,覆盖前一个标志生成的任何内容。就好像我们定义了两个Actions
具有相同dest
但不同True/False
const 的 。
关键是它定义了两个标志字符串:
option_strings=['--foo', '--no-foo']
Run Code Online (Sandbox Code Playgroud)
这个新类的部分代码:
class BooleanOptionalAction(Action):
def __init__(self,
option_strings,
dest,
...):
_option_strings = []
for option_string in option_strings:
_option_strings.append(option_string)
if option_string.startswith('--'):
option_string = '--no-' + option_string[2:]
_option_strings.append(option_string)
...
def __call__(self, parser, namespace, values, option_string=None):
if option_string in self.option_strings:
setattr(namespace, self.dest, not option_string.startswith('--no-'))
Run Code Online (Sandbox Code Playgroud)
因此该操作__init__
定义了两个标志以及__call__
该no
部分的检查。
是否add_mutually_exclusive_group()
的argparse
帮助?
parser = argparse.ArgumentParser()
exclusive_grp = parser.add_mutually_exclusive_group()
exclusive_grp.add_argument('--foo', action='store_true', help='do foo')
exclusive_grp.add_argument('--no-foo', action='store_true', help='do not do foo')
args = parser.parse_args()
print 'Starting program', 'with' if args.foo else 'without', 'foo'
print 'Starting program', 'with' if args.no_foo else 'without', 'no_foo'
Run Code Online (Sandbox Code Playgroud)
以下是运行时的外观:
./so.py --help
usage: so.py [-h] [--foo | --no-foo]
optional arguments:
-h, --help show this help message and exit
--foo do foo
--no-foo do not do foo
./so.py
Starting program without foo
Starting program without no_foo
./so.py --no-foo --foo
usage: so.py [-h] [--foo | --no-foo]
so.py: error: argument --foo: not allowed with argument --no-foo
Run Code Online (Sandbox Code Playgroud)
这与互斥组中的以下不同,在程序中不允许任何选项(并且我假设您因语法而需要选项--
).这意味着一个或另一个:
parser.add_argument('--foo=', choices=('y', 'n'), default='y',
help="Do foo? (default y)")
Run Code Online (Sandbox Code Playgroud)
如果这些是必需的(非选购),也许add_subparsers()
正在使用你正在寻找的东西.
更新1
逻辑上不同,但可能更清洁:
...
exclusive_grp.add_argument('--foo', action='store_true', dest='foo', help='do foo')
exclusive_grp.add_argument('--no-foo', action='store_false', dest='foo', help='do not do foo')
args = parser.parse_args()
print 'Starting program', 'with' if args.foo else 'without', 'foo'
Run Code Online (Sandbox Code Playgroud)
运行它:
./so.py --foo
Starting program with foo
./so.py --no-foo
Starting program without foo
./so.py
Starting program without foo
Run Code Online (Sandbox Code Playgroud)
我修改了@Omnifarious的解决方案,使其更像标准操作:
import argparse
class ActionNoYes(argparse.Action):
def __init__(self, option_strings, dest, default=None, required=False, help=None):
if default is None:
raise ValueError('You must provide a default with Yes/No action')
if len(option_strings)!=1:
raise ValueError('Only single argument is allowed with YesNo action')
opt = option_strings[0]
if not opt.startswith('--'):
raise ValueError('Yes/No arguments must be prefixed with --')
opt = opt[2:]
opts = ['--' + opt, '--no-' + opt]
super(ActionNoYes, self).__init__(opts, dest, nargs=0, const=None,
default=default, required=required, help=help)
def __call__(self, parser, namespace, values, option_strings=None):
if option_strings.startswith('--no-'):
setattr(namespace, self.dest, False)
else:
setattr(namespace, self.dest, True)
Run Code Online (Sandbox Code Playgroud)
您可以像添加任何标准选项一样添加是/否参数。您只需要ActionNoYes
在action
参数中传递类:
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action=ActionNoYes, default=False)
Run Code Online (Sandbox Code Playgroud)
现在,当您调用它时:
>> args = parser.parse_args(['--foo'])
Namespace(foo=True)
>> args = parser.parse_args(['--no-foo'])
Namespace(foo=False)
>> args = parser.parse_args([])
Namespace(foo=False)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5043 次 |
最近记录: |