Salvatore
Salvatore

Reputation: 11934

Python check if an argument was passed in by position or by keyword

What is a cleaner way to check if an argument was passed in by position or by keyword?

I am cloning and overriding functions under certain circumstances. The signatures of the overridden functions may grow over time, so I want something I won't have to change later, that I can use to extract only the couple of parameters I care about and ignore all the rest.

For example, the function call may look like this:

foo("bar", "baz")
foo(arg1="bar", arg2="baz")

Both are valid. If I am using args and kwargs to catch all the parameters, I have to figure out which one it ended up in. So far I'm doing this:

def foo(*args, **kwargs): 
    arg1 = kwargs["arg1"] if "arg1" in kwargs else args[0]
    arg2 = kwargs["arg2"] if "arg2" in kwargs else args[1]

I feel like there has to be a cleaner way to do this.

Upvotes: 1

Views: 1099

Answers (1)

alani
alani

Reputation: 13069

You could do:

def foo(*args, **kwargs):
    argnames = ["arg1", "arg2"]

    argdict = dict(zip(argnames, args))
    argdict.update(kwargs)

    print(argdict)


foo("bar", "baz")
foo(arg1="bar", arg2="baz")

Both give the same:

{'arg1': 'bar', 'arg2': 'baz'}
{'arg1': 'bar', 'arg2': 'baz'}

Then if you really need you can do arg1 = argdict["arg1"] etc, but you might as well just use a dictionary rather than extract into named variables.

(Using string constants "bar" and "baz" here, rather than bar and baz, for sake of a self-contained example, but it is not dependent on them being strings.)

Upvotes: 2

Related Questions