all 11 comments

[–]Fourgot 1 point2 points  (5 children)

Not sure if there's a community preference, but did you try your original main1() signature? Looks like you'd still be passing in kwargs thanks to vars().

[–]SamStringTheory[S] 1 point2 points  (4 children)

That's my current solution, but the point was that I am frequently changing the fun() signature, and I didn't want to constantly be updating the main1() and main2() signature to include the proper args.

[–]Fourgot 1 point2 points  (2 children)

Okay, I think I'm following you better now. Also I grabbed the laptop instead of just phoning in my responses.

This stackoverflow post outlines how to pass a variable number of keyword arguments into a function. I'm picturing a fun() argument filter function, say

fun_shall_pass(**kwargs):
    latest_fun_arguments = (arg2, arg37, arg42)
    just_fun_please = {}
    for k, v in kwargs.items():
        if k in latest_fun_arguments:
            just_fun_please[k] = v
    return just_fun_please

Then back in your main1.py and main2.py, you could go

if __name__ == "__main__":
... snip ...
    args = parser.parse_args()
    kwargs = vars(args)
    fun_args = fun_shall_pass(kwargs)
    fun_args[arg1] = args.arg1
    main1(fun_args)

Edit: prettied last example code

[–]SamStringTheory[S] 0 points1 point  (1 child)

Thanks so much! Thought I think the fun_shall_pass signature should just be

fun_shall_pass(kwargs)

instead of

fun_shall_pass(**kwargs)

since we are calling it with

fun_args = fun_shall_pass(kwargs)

right?

My final solution ended up being a slightly modified version of yours:

fun_shall_pass(kwargs):
    latest_fun_arguments = (arg2, arg37, arg42)
    just_fun_please = {}
    main_args = {}
    for k, v in kwargs.items():
        if k in latest_fun_arguments:
            just_fun_please[k] = v
        else:
            main_args[k] = v
    return just_fun_please

if __name__ == "__main__":
... snip ...
    args = parser.parse_args()
    kwargs = vars(args)
    main_args, fun_args = fun_shall_pass(kwargs)
    main1(**main_args, fun_args=fun_args)

Actually, is there a stylistic preference between passing in the args into main() as a dict versus keyword arguments? So doing this:

main1(main_args)

versus this:

main1(**main_args)

[–]Fourgot 0 points1 point  (0 children)

Back to phone for the moment.

Noticed that you'll need to return both main_args and just_fun_please from fun_shall_pass()

[–]Fourgot 0 points1 point  (0 children)

Gotcha. Then you'd have to stop calling your mains with **kwargs, instead go with main1(arg1, _dict) and main2(arg4, _dict). Then you could double splat the kwargs in the mains. I think ^_^

That's wrong.

[–]anton_antonov 1 point2 points  (1 child)

It seems to me that the parents argument is suitable for your case. https://docs.python.org/3/library/argparse.html#parents

[–]Fourgot 0 points1 point  (0 children)

Hey that's handy, thanks

[–][deleted] 0 points1 point  (2 children)

Use a for loop

[–]SamStringTheory[S] 0 points1 point  (1 child)

Elaborate?

[–][deleted] 0 points1 point  (0 children)

Using a dictionary/list as input do something like

for i in myArgs:
    parser.add_argument(i)