如何在 Python 2.x 中合并两个 argparse 命名空间?
How can I merge two argparse Namespaces in Python 2.x?
我想合并 Python 2.x 中的 2 argparse.Namespace
个对象。
在 python 3.x 我可以做这样的事情:
from argparse import Namespace
# The 2 initial objects
options_foo = Namespace(foo="foo")
options_bar = Namespace(bar="bar")
# the merged object
options_baz = Namespace(**vars(options_foo), **vars(options_bar))
并得到:
print(options_baz)
# Namespace(foo="foo", bar="bar")
但是在 python 2.x 我不能。我收到以下错误。
SyntaxError: invalid syntax
有没有简单的方法可以做到这一点?
这是一个合并两个参数的函数:
def merge_args_safe(args1: Namespace, args2: Namespace) -> Namespace:
"""
Merges two namespaces but throws an error if there are keys that collide.
ref:
:param args1:
:param args2:
:return:
"""
# - the merged args
# The vars() function returns the __dict__ attribute to values of the given object e.g {field:value}.
args = Namespace(**vars(args1), **vars(args2))
return args
测试
def merge_args_test():
args1 = Namespace(foo="foo", collided_key='from_args1')
args2 = Namespace(bar="bar", collided_key='from_args2')
args = merge_args(args1, args2)
print('-- merged args')
print(f'{args=}')
输出:
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd.py", line 1483, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/Users/brando/ultimate-utils/ultimate-utils-proj-src/uutils/__init__.py", line 1202, in <module>
merge_args_test()
File "/Users/brando/ultimate-utils/ultimate-utils-proj-src/uutils/__init__.py", line 1192, in merge_args_test
args = merge_args(args1, args2)
File "/Users/brando/ultimate-utils/ultimate-utils-proj-src/uutils/__init__.py", line 1116, in merge_args
args = Namespace(**vars(args1), **vars(args2))
TypeError: argparse.Namespace() got multiple values for keyword argument 'collided_key'
python-BaseException
你可以在这个图书馆找到它:https://github.com/brando90/ultimate-utils
如果您想解决冲突,请执行以下操作:
def merge_two_dicts(starting_dict: dict, updater_dict: dict) -> dict:
"""
Starts from base starting dict and then adds the remaining key values from updater replacing the values from
the first starting/base dict with the second updater dict.
For later: how does d = {**d1, **d2} replace collision?
:param starting_dict:
:param updater_dict:
:return:
"""
new_dict: dict = starting_dict.copy() # start with keys and values of starting_dict
new_dict.update(updater_dict) # modifies starting_dict with keys and values of updater_dict
return new_dict
def merge_args(args1: Namespace, args2: Namespace) -> Namespace:
"""
ref:
:param args1:
:param args2:
:return:
"""
# - the merged args
# The vars() function returns the __dict__ attribute to values of the given object e.g {field:value}.
merged_key_values_for_namespace: dict = merge_two_dicts(vars(args1), vars(args2))
args = Namespace(**merged_key_values_for_namespace)
return args
测试:
def merge_args_test():
args1 = Namespace(foo="foo", collided_key='from_args1')
args2 = Namespace(bar="bar", collided_key='from_args2')
args = merge_args(args1, args2)
print('-- merged args')
print(f'{args=}')
assert args.collided_key == 'from_args2', 'Error in merge dict, expected the second argument to be the one used' \
'to resolve collision'
我主要重新考虑了这个答案,因为我没有完全阅读和理解你的问题...
确实这行在Python3有效,在Python2无效:
options_baz = Namespace(**vars(options_foo), **vars(options_bar))
当我们查看错误时,我们看到 Python2 不能接受的是逗号 (,
):
File "main.py", line 8
options_baz = Namespace(**vars(options_foo), **vars(options_bar))
^
SyntaxError: invalid syntax
所以,让我们避免将两组选项传递给 Namespace()
初始值设定项:
...
dict_baz = vars(options_foo)
dict_baz.update(vars(options_bar))
# the merged object
options_baz = Namespace(**dict_baz)
print(options_baz)
我们得到:
Namespace(bar='bar', foo='foo')
在另一个回答中,您指出 double-star (**
) 语法无效,但这绝对是有效的语法。我们可以看到它早在 Python 2.2:
就被提及了
If the syntax **expression
appears in the function call,
expression
must evaluate to a (subclass of) dictionary, ...
一直都是那个逗号。
我想合并 Python 2.x 中的 2 argparse.Namespace
个对象。
在 python 3.x 我可以做这样的事情:
from argparse import Namespace
# The 2 initial objects
options_foo = Namespace(foo="foo")
options_bar = Namespace(bar="bar")
# the merged object
options_baz = Namespace(**vars(options_foo), **vars(options_bar))
并得到:
print(options_baz)
# Namespace(foo="foo", bar="bar")
但是在 python 2.x 我不能。我收到以下错误。
SyntaxError: invalid syntax
有没有简单的方法可以做到这一点?
这是一个合并两个参数的函数:
def merge_args_safe(args1: Namespace, args2: Namespace) -> Namespace:
"""
Merges two namespaces but throws an error if there are keys that collide.
ref:
:param args1:
:param args2:
:return:
"""
# - the merged args
# The vars() function returns the __dict__ attribute to values of the given object e.g {field:value}.
args = Namespace(**vars(args1), **vars(args2))
return args
测试
def merge_args_test():
args1 = Namespace(foo="foo", collided_key='from_args1')
args2 = Namespace(bar="bar", collided_key='from_args2')
args = merge_args(args1, args2)
print('-- merged args')
print(f'{args=}')
输出:
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd.py", line 1483, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/Users/brando/ultimate-utils/ultimate-utils-proj-src/uutils/__init__.py", line 1202, in <module>
merge_args_test()
File "/Users/brando/ultimate-utils/ultimate-utils-proj-src/uutils/__init__.py", line 1192, in merge_args_test
args = merge_args(args1, args2)
File "/Users/brando/ultimate-utils/ultimate-utils-proj-src/uutils/__init__.py", line 1116, in merge_args
args = Namespace(**vars(args1), **vars(args2))
TypeError: argparse.Namespace() got multiple values for keyword argument 'collided_key'
python-BaseException
你可以在这个图书馆找到它:https://github.com/brando90/ultimate-utils
如果您想解决冲突,请执行以下操作:
def merge_two_dicts(starting_dict: dict, updater_dict: dict) -> dict:
"""
Starts from base starting dict and then adds the remaining key values from updater replacing the values from
the first starting/base dict with the second updater dict.
For later: how does d = {**d1, **d2} replace collision?
:param starting_dict:
:param updater_dict:
:return:
"""
new_dict: dict = starting_dict.copy() # start with keys and values of starting_dict
new_dict.update(updater_dict) # modifies starting_dict with keys and values of updater_dict
return new_dict
def merge_args(args1: Namespace, args2: Namespace) -> Namespace:
"""
ref:
:param args1:
:param args2:
:return:
"""
# - the merged args
# The vars() function returns the __dict__ attribute to values of the given object e.g {field:value}.
merged_key_values_for_namespace: dict = merge_two_dicts(vars(args1), vars(args2))
args = Namespace(**merged_key_values_for_namespace)
return args
测试:
def merge_args_test():
args1 = Namespace(foo="foo", collided_key='from_args1')
args2 = Namespace(bar="bar", collided_key='from_args2')
args = merge_args(args1, args2)
print('-- merged args')
print(f'{args=}')
assert args.collided_key == 'from_args2', 'Error in merge dict, expected the second argument to be the one used' \
'to resolve collision'
我主要重新考虑了这个答案,因为我没有完全阅读和理解你的问题...
确实这行在Python3有效,在Python2无效:
options_baz = Namespace(**vars(options_foo), **vars(options_bar))
当我们查看错误时,我们看到 Python2 不能接受的是逗号 (,
):
File "main.py", line 8
options_baz = Namespace(**vars(options_foo), **vars(options_bar))
^
SyntaxError: invalid syntax
所以,让我们避免将两组选项传递给 Namespace()
初始值设定项:
...
dict_baz = vars(options_foo)
dict_baz.update(vars(options_bar))
# the merged object
options_baz = Namespace(**dict_baz)
print(options_baz)
我们得到:
Namespace(bar='bar', foo='foo')
在另一个回答中,您指出 double-star (**
) 语法无效,但这绝对是有效的语法。我们可以看到它早在 Python 2.2:
If the syntax
**expression
appears in the function call,expression
must evaluate to a (subclass of) dictionary, ...
一直都是那个逗号。