Skip to content Skip to sidebar Skip to footer

How Can I Merge Two Argparse Namespaces In Python 2.x?

I want to merge 2 argparse.Namespace objects in Python 2.x. In python 3.x I can do something like this: from argparse import Namespace # The 2 initial objects options_foo = Namesp

Solution 1:

Here is a function that merges two args:

defmerge_args_safe(args1: Namespace, args2: Namespace) -> Namespace:"""
    Merges two namespaces but throws an error if there are keys that collide.

    ref: https://stackoverflow.com/questions/56136549/how-can-i-merge-two-argparse-namespaces-in-python-2-x
    :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

test

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=}')

output:

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

you can find it in this library: https://github.com/brando90/ultimate-utils


If you want to have collisions resolved do this:

defmerge_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_dictreturn new_dict

defmerge_args(args1: Namespace, args2: Namespace) -> Namespace:"""

    ref: https://stackoverflow.com/questions/56136549/how-can-i-merge-two-argparse-namespaces-in-python-2-x
    :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

test:

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'

Post a Comment for "How Can I Merge Two Argparse Namespaces In Python 2.x?"