我怎样才能轻松地创建一个 python argparse 参数?
How can I easily create a python argparse argument with an inverse?
使用 argparse 和 Python 3,我想创建一对互补的参数:
--log-file=~/some-default-log-filename.txt
--no-log-file
如示例所示,默认情况下,日志文件参数将具有默认值(文件名)。您可以通过为 --log-file
指定不同的字符串值来更改它,或者通过指定 --no-log-file
.
来完全删除日志文件
在 argparse 中执行此操作的优雅方法是什么?我根本找不到任何方法来做 inverse/complementary 参数,不介意在哪里有字符串参数。
最好是当我执行 args = parser.parse_args()
时,args.log_file
包含日志文件名(包括默认文件名)或 None
如果 no-log-file
选项已指定。
这不是完全你要找的东西,但我会按如下方式进行:
parser.add_argument(
"--log-file",
const="~/some-default-log-filename.txt",
default=None,
dest="log_file",
nargs="?"
)
这处理三种情况:
... --log-file mylog.txt ...
- 登录到用户指定的文件;
... --log-file ...
- 登录到 const
默认文件;和
...
- 使用 default
值 None
。
有关详细信息,请参阅 the docs on nargs
。
检查此结尾以获得基于 store_const
的解决方案。
我记得看到一个旧的 python bug 问题,它建议使用一些可以自动处理 --foo
和 --no-foo
以及其他一些变体的代码来扩展 argparse
。也许我稍后会找到它。
但目前 argparse
没有符合您规格的机制。
带有 const
和 default
的 nargs='?'
旨在处理像您这样的 3 折盒。
# no --foo, assign the 'default'
--foo # without arg, assign the 'const'
--foo arg # assign the supplied string
虽然语法不是您想要的,但我认为它为您的用户提供了相同的控制权。
为了更接近您想要的语法,您必须同时创建 logfile
参数和 no-log
参数,然后使用简单的 pos-parsing 测试 'merge'两人
parser.add_argument('--log-file', ....)
parser.add_argument('--no-log', action='store_true')
及以后:
if args.no_log:
args.log_file = None
如果您必须像这样创建许多参数对,您可以定义一个辅助函数:
def make_inverse_arg(parser, *args, **kwargs):
parser.add_argument(*args, **kwargs)
# define inverse
arg1 = '--no-'+args[1][2:]
parser.add_argument(arg1, action='store_true')
# could be more robust, but you get the idea
def post_test():
...
return post_test
如果 --no-foo
定义为 'store_const' 参数,const=None
和与 --foo
相同的目标,那么它只会将 None
放入命名空间当它存在时。 default=SUPPRESS
确保它不会将自己的默认值放入命名空间。
parser=argparse.ArgumentParser()
parser.add_argument('--no-foo', dest='foo', action='store_const', const=None,
default=argparse.SUPPRESS)
parser.add_argument('--foo',default='test')
In [329]: parser.parse_args([])
Out[329]: Namespace(foo='test')
In [330]: parser.parse_args('--foo xxx'.split())
Out[330]: Namespace(foo='xxx')
In [331]: parser.parse_args('--foo xxx --no-foo'.split())
Out[331]: Namespace(foo=None)
In [332]: parser.parse_args('--no-foo --foo xxx'.split())
Out[332]: Namespace(foo='xxx')
In [333]: parser.parse_args('--no-foo'.split())
Out[333]: Namespace(foo=None)
如果存在冲突,--foo
和 --no-foo
中的最后一个决定命名空间中的内容。
使用 argparse 和 Python 3,我想创建一对互补的参数:
--log-file=~/some-default-log-filename.txt
--no-log-file
如示例所示,默认情况下,日志文件参数将具有默认值(文件名)。您可以通过为 --log-file
指定不同的字符串值来更改它,或者通过指定 --no-log-file
.
在 argparse 中执行此操作的优雅方法是什么?我根本找不到任何方法来做 inverse/complementary 参数,不介意在哪里有字符串参数。
最好是当我执行 args = parser.parse_args()
时,args.log_file
包含日志文件名(包括默认文件名)或 None
如果 no-log-file
选项已指定。
这不是完全你要找的东西,但我会按如下方式进行:
parser.add_argument(
"--log-file",
const="~/some-default-log-filename.txt",
default=None,
dest="log_file",
nargs="?"
)
这处理三种情况:
... --log-file mylog.txt ...
- 登录到用户指定的文件;... --log-file ...
- 登录到const
默认文件;和...
- 使用default
值None
。
有关详细信息,请参阅 the docs on nargs
。
检查此结尾以获得基于 store_const
的解决方案。
我记得看到一个旧的 python bug 问题,它建议使用一些可以自动处理 --foo
和 --no-foo
以及其他一些变体的代码来扩展 argparse
。也许我稍后会找到它。
但目前 argparse
没有符合您规格的机制。
带有 const
和 default
的 nargs='?'
旨在处理像您这样的 3 折盒。
# no --foo, assign the 'default'
--foo # without arg, assign the 'const'
--foo arg # assign the supplied string
虽然语法不是您想要的,但我认为它为您的用户提供了相同的控制权。
为了更接近您想要的语法,您必须同时创建 logfile
参数和 no-log
参数,然后使用简单的 pos-parsing 测试 'merge'两人
parser.add_argument('--log-file', ....)
parser.add_argument('--no-log', action='store_true')
及以后:
if args.no_log:
args.log_file = None
如果您必须像这样创建许多参数对,您可以定义一个辅助函数:
def make_inverse_arg(parser, *args, **kwargs):
parser.add_argument(*args, **kwargs)
# define inverse
arg1 = '--no-'+args[1][2:]
parser.add_argument(arg1, action='store_true')
# could be more robust, but you get the idea
def post_test():
...
return post_test
如果 --no-foo
定义为 'store_const' 参数,const=None
和与 --foo
相同的目标,那么它只会将 None
放入命名空间当它存在时。 default=SUPPRESS
确保它不会将自己的默认值放入命名空间。
parser=argparse.ArgumentParser()
parser.add_argument('--no-foo', dest='foo', action='store_const', const=None,
default=argparse.SUPPRESS)
parser.add_argument('--foo',default='test')
In [329]: parser.parse_args([])
Out[329]: Namespace(foo='test')
In [330]: parser.parse_args('--foo xxx'.split())
Out[330]: Namespace(foo='xxx')
In [331]: parser.parse_args('--foo xxx --no-foo'.split())
Out[331]: Namespace(foo=None)
In [332]: parser.parse_args('--no-foo --foo xxx'.split())
Out[332]: Namespace(foo='xxx')
In [333]: parser.parse_args('--no-foo'.split())
Out[333]: Namespace(foo=None)
如果存在冲突,--foo
和 --no-foo
中的最后一个决定命名空间中的内容。