- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有两个类 A 和 B,每个类都定义了自己的参数解析器(使用 argparse)
我现在想向 A 添加功能,以便它调用 B 类。我正在使用组合来执行此操作(即 A 具有对象 B 的实例)
我在这里询问了如何组合两个 arg 解析对象,以便 argparseA 现在将在问题 Can two Python argparse objects be combined? 中包含 argparseB 中的参数。
我的问题如下: A 和 B 都有同名的参数。但是-我需要用户输入两个不同的值(即 argpaseA.val1 需要获取值 argparseA.val1 和 argParseB.val1)
(显而易见的解决方案是在 argparseA 或 argpaseB 中重命名 val1,但是已经有 50 多个脚本继承了 A 类,还有 50 个脚本继承了 B 类,所以我希望对 A 和 B 的更改尽可能小。)
我想向 argpaseA 添加一个新的且名称不同的参数,称为 val2,然后可以将其作为 val1 传递给 argparseB。
我的问题是-从 argparseA 到 argparseB 进行这种转换或参数的正确方法是什么?
或者有没有更好的方法来设计这个?
最佳答案
我猜你正在尝试我的parents
建议,并说明可能发生的情况。但即使您采用了另一种方法,这也可能会有所帮助。
import argparse
parserA=argparse.ArgumentParser()
a1=parserA.add_argument('-f','--foo','--bar')
print(a1)
print()
parserB=argparse.ArgumentParser()
b1=parserB.add_argument('-g','--goo','--bar')
print(b1)
b1.dest='bar' # can change attributes like dest after creation
print()
# parser with parents; not the conflict_handler
parserC=argparse.ArgumentParser(conflict_handler='resolve',
parents=[parserA, parserB])
print(parserC._actions) # the actions (arguments) of C
print()
parserA.print_help()
print()
parserC.print_help() # uses the C._actions
1445:~/mypy$ python3 stack38071986.py
_StoreAction(option_strings=['-f', '--foo', '--bar'], dest='foo',
nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
_StoreAction(option_strings=['-g', '--goo', '--bar'], dest='goo',
nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
[_StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None,
const=None, default=None, type=None, choices=None, help=None, metavar=None),
_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0,
const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=['-g', '--goo', '--bar'], dest='bar',
nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
usage: stack38071986.py [-f FOO]
optional arguments:
help show this help message and exit
-f FOO, --foo FOO
usage: stack38071986.py [-f FOO] [-h] [-g BAR]
optional arguments:
-f FOO, --foo FOO
-h, --help show this help message and exit
-g BAR, --goo BAR, --bar BAR
store
行为是存储
value
在
dest
args
中的属性命名空间,
setattr(namespace, action.dest, value)
.
dest
默认是第一个长选项字符串(减去 --),但可以设置为参数(用于选项),或者在创建之后。
conflict_handler
被唤起。默认处理程序会引发错误,但这里我使用
resolve
处理程序。它试图删除足够多的现有论点来解决冲突。
-h
(帮助)行动。
resolve
在
parserC
删除除一个以外的所有内容。请注意
[-h]
parserA
中缺少帮助。
--bar
定义于
parserB
与
parserA
中的相同字符串冲突.
resolve
已将其从 A 的定义中删除,但
-f
和
--foo
保持。
parserC
弄乱了其他解析器;所以我建议只使用
parserC.parse_args()
在这次运行中。
conflict_handler
方法。
resolve
一个有一些粗糙的边缘,并且不经常使用。
argparse
文档并不是其行为的硬道理,而且比代码本身更容易更改。开发人员在进行更改时几乎对向后冲突感到偏执。
resolve
的尝试。冲突处理程序
import argparse
def pp(adict):
for k in adict:
v=adict[k]
print('Action %10s:'%k,v.option_strings, v.dest)
def new_resolve(self, action, conflicting_actions):
rename_dict={'--var':'--var1'}
for option_string, action in conflicting_actions:
new_string = rename_dict.get(option_string, None)
if new_string:
# rename rather than replace
print(action.option_strings)
action.option_strings = [new_string]
action.dest = new_string[2:]
pp(self._option_string_actions)
a1=self._option_string_actions.pop(option_string, None)
print(a1)
self._option_string_actions[new_string] = a1
pp(self._option_string_actions)
else:
# regular remove action
action.option_strings.remove(option_string)
self._option_string_actions.pop(option_string, None)
# if the option now has no option string, remove it from the
# container holding it
if not action.option_strings:
action.container._remove_action(action)
argparse._ActionsContainer._handle_conflict_resolve=new_resolve
parserA=argparse.ArgumentParser()
a1=parserA.add_argument('-f','--foo')
a1=parserA.add_argument('--var')
parserB=argparse.ArgumentParser()
b1=parserB.add_argument('-g','--goo')
b1=parserB.add_argument('--var')
parserC=argparse.ArgumentParser(conflict_handler='resolve',
parents=[parserA, parserB],
add_help=False)
parserA.print_help()
print()
parserC.print_help()
print(parserC.parse_args())
1027:~/mypy$ python3 stack38071986.py --var1 1 --var 3
['--var']
Action --var: ['--var1'] var1
Action -g: ['-g', '--goo'] goo
Action --foo: ['-f', '--foo'] foo
Action -h: ['-h', '--help'] help
Action --goo: ['-g', '--goo'] goo
Action --help: ['-h', '--help'] help
Action -f: ['-f', '--foo'] foo
_StoreAction(option_strings=['--var1'], dest='var1', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
Action -g: ['-g', '--goo'] goo
Action --var1: ['--var1'] var1
Action --foo: ['-f', '--foo'] foo
Action -h: ['-h', '--help'] help
Action --goo: ['-g', '--goo'] goo
Action --help: ['-h', '--help'] help
Action -f: ['-f', '--foo'] foo
usage: stack38071986.py [-f FOO] [--var1 VAR1]
optional arguments:
help show this help message and exit
-f FOO, --foo FOO
--var1 VAR1
usage: stack38071986.py [-f FOO] [--var1 VAR1] [-h] [-g GOO] [--var VAR]
optional arguments:
-f FOO, --foo FOO
--var1 VAR1
-h, --help show this help message and exit
-g GOO, --goo GOO
--var VAR
Namespace(foo=None, goo=None, var='3', var1='1')
ArgumentParser
添加一个新的。添加自定义很容易
Action
和
FormatHandler
类,但这并不容易。我的猜测是没有人尝试过这种定制。
resolve
方法,并将其链接到 - 运行中。不干净,但足以进行测试。
action
参数),但不知道新 Action 的身份(即来自 ParserA 的
--var
,但不知道来自 ParserB 的
--var
)。因此,我正在修改现有名称的“名称”。现在这个方法必须知道,通过它的
rename_dict
要替换的选项字符串和新名称。
parents
的自定义版本可能会更容易。机制。一种可以用作:
parserC = argparse.ArgumentParser()
parserC.add_argument(...) # C's own arguments
copy_arguments(parserC, [parserA, parserB], rename_dict={...})
parents
机制,让我指定
skip_list
和
replace_dict
. (我可能会删除关于解决方案)。
import argparse
def add_actions(parser, other, skip_list=None, rename_dict=None):
# adapted from _add_container_actions (used for parents)
# copy (by reference) selected actions from other to parser
# can skip actions (to avoid use of conflict_handler)
# can rename other actions (again to avoid conflict)
if skip_list is None:
skip_list = ['-h','--help']
if rename_dict is None:
rename_dict = {}
# group handling as before
# collect groups by titles
title_group_map = {}
for group in parser._action_groups:
if group.title in title_group_map:
msg = _('cannot merge actions - two groups are named %r')
raise ValueError(msg % (group.title))
title_group_map[group.title] = group
# map each action to its group
group_map = {}
for group in other._action_groups:
# if a group with the title exists, use that, otherwise
# create a new group matching the other's group
if group.title not in title_group_map:
title_group_map[group.title] = parser.add_argument_group(
title=group.title,
description=group.description,
conflict_handler=group.conflict_handler)
# map the actions to their new group
for action in group._group_actions:
group_map[action] = title_group_map[group.title]
# add other's mutually exclusive groups
# NOTE: if add_mutually_exclusive_group ever gains title= and
# description= then this code will need to be expanded as above
for group in other._mutually_exclusive_groups:
mutex_group = parser.add_mutually_exclusive_group(
required=group.required)
# map the actions to their new mutex group
for action in group._group_actions:
group_map[action] = mutex_group
# add all actions to this other or their group
# addition with skip and rename
for action in other._actions:
option_strings = action.option_strings
if any([s for s in option_strings if s in skip_list]):
print('skipping ', action.dest)
continue
else:
sl = [s for s in option_strings if s in rename_dict]
if len(sl):
mod = rename_dict[sl[0]]
action.dest = action.dest+mod
action.option_strings = [option_strings[0]+mod]
group_map.get(action, parser)._add_action(action)
parserA=argparse.ArgumentParser()
a1=parserA.add_argument('-f','--foo')
a1=parserA.add_argument('--var')
parserB=argparse.ArgumentParser()
b1=parserB.add_argument('-g','--goo')
b1=parserB.add_argument('--var')
parserC=argparse.ArgumentParser()
# parserC.add_argument('baz')
add_actions(parserC, parserA, rename_dict={'--var':'A'})
add_actions(parserC, parserB, rename_dict={'--var':'B'})
parserC.print_help()
print(parserC.parse_args())
2245:~/mypy$ python3 stack38071986_1.py --varA 1 --varB 3
skipping help
skipping help
usage: stack38071986_1.py [-h] [-f FOO] [--varA VARA] [-g GOO] [--varB VARB]
optional arguments:
-h, --help show this help message and exit
-f FOO, --foo FOO
--varA VARA
-g GOO, --goo GOO
--varB VARB
Namespace(foo=None, goo=None, varA='1', varB='3')
print('parserC actions')
for action in parserC._actions:
print(action.option_strings, action.dest)
parserC actions
['-h', '--help'] help
['-f', '--foo'] foo
['--varA'] varA
['-g', '--goo'] goo
['--varB'] varB
_actions
是解析器的 Action (参数)列表。它是“隐藏的”,因此请谨慎使用,但我预计不会像这样的基本属性发生任何变化。您可以修改这些操作的许多属性,例如
dest
dest
中的一些:
for action in parserC._actions:
if action.dest.startswith('var'):
action.dest = action.dest+'_C'
print(parserC.parse_args())
Namespace(foo=None, goo=None, varA_C=None, varB_C='one')
关于python - 当 Python argparse 中存在命名冲突时,如何从命令行获取 2 个不同对象的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38071986/
我正在尝试使用 parser = argparse.ArgumentParser对于我写的一个小程序。 程序接受作为输入 EITHER ( txt 文件的路径 ) OR ( opt1 && opt2
我为需要遵循特定格式的参数定义了自定义正则表达式类型。我使用了另一篇文章 ( regex custom type ) 中的代码,它非常有用。我的问题是我正在编写单元测试,我希望正则表达式失败并尝试断言
我写了下面的代码。 import argparse parser = argparse.ArgumentParser() parser.add_argument('-v', '--version',
我一定遗漏了一些明显的东西。目标是使用 argparse,第一个参数是必需的,第二个是可选的,其他任何剩余参数都是可选的。 为了展示这个问题,我制作了两个测试解析器;它们之间的唯一区别是在一个中使用
我正在努力寻找一种将参数传递给 docker container 中的 python 脚本的方法。基于ubuntu 。我正在与docker-compose.yml合作. 请查看下面的示例! docke
我正在努力寻找一种将参数传递给 docker container 中的 python 脚本的方法。基于ubuntu 。我正在与docker-compose.yml合作. 请查看下面的示例! docke
我像这样创建一个 argparser: parser = argparse.ArgumentParser(description='someDesc') parser.add_argument
我正在编写一个脚本,其中包含 2 个相互排斥的参数,以及一个仅对其中一个参数有意义的选项。如果您使用毫无意义的参数调用它,我会尝试将 argparse 设置为失败。 要清楚: -m -f 有意义 -s
我正在使用 Python 3.6 和 argparse 1.1。 除了 -h/--help 我还想有一个选项 -v/--version打印带有版本信息的字符串并退出程序(就像使用帮助字符串一样)。但是
有没有办法将来自父解析器的参数分组到不同的组中?我无权访问父解析器本身,所以我不能在那里添加组。 (我使用的是 Google 的 OAuth2 框架)。 目前我的代码是: # test.py from
GNU grep 有一个参数可以在匹配行周围打印一定数量的额外行。从手册页: -C NUM, -NUM, --context=NUM Print NUM lines of output context
现在,我有一个脚本可以使用 argparse 接受命令行参数。例如,像这样: #foo.py def function_with_args(optional_args=None): parser
我在脚本中的 argparse 解析器中添加了一些参数,如下所示: parser = argparse.ArgumentParser() parser.add_argument("--eval_mod
我在 python 代码中使用 argparse 作为参数解析器。将字典解析为 argparse 对象的最佳方法是什么? 例如,我的字典是: { "activation_dropout": 0
我正在使用 argparse从命令行接收输入以运行我的脚本。 我当前的输入字符串如下所示: path> python -t T1 T2 T3 -f F1 F2 argparse 中是否有一个参数,而
我看到了有关使用 argparse 库将字典和列表传递给 Python 的问题。这些示例都显示了我的 Python 代码的样子。但是没有人告诉我它们在命令行上的样子。我在哪里需要大括号、方括号和引号?
我想模拟大多数命令行实用程序的行为,其中可选参数可以放在命令行中的任何位置,包括位置参数之间,例如 mkdir例子: mkdir before --mode 077 after 在这种情况下,我们知道
我想获取传递给 sys.argv 的所有参数有格式someprogram.py --someparameter 23 -p 42 -anotherparam somevalue . 结果我正在寻找一个
这个问题在这里已经有了答案: Argparse optional positional arguments? (3 个回答) 1年前关闭。 我如何才能设置我的 argparser 以具有以下行为? b
这是我的简单 test.py 脚本: import argparse parser = argparse.ArgumentParser('A long string that goes on and
我是一名优秀的程序员,十分优秀!