Can you list the keyword arguments a function receives?
A little nicer than inspecting the code object directly and working out the variables is to use the inspect module.
>>> import inspect
>>> def func(a,b,c=42, *args, **kwargs): pass
>>> inspect.getargspec(func)
(['a', 'b', 'c'], 'args', 'kwargs', (42,))
If you want to know if its callable with a particular set of args, you need the args without a default already specified. These can be got by:
def get_required_args(func):
args, varargs, varkw, defaults = inspect.getargspec(func)
if defaults:
args = args[:-len(defaults)]
return args # *args and **kwargs are not required, so ignore them.
Then a function to tell what you are missing from your particular dict is:
def missing_args(func, argdict):
return set(get_required_args(func)).difference(argdict)
Similarly, to check for invalid args, use:
def invalid_args(func, argdict):
args, varargs, varkw, defaults = inspect.getargspec(func)
if varkw: return set() # All accepted
return set(argdict) - set(args)
And so a full test if it is callable is :
def is_callable_with_args(func, argdict):
return not missing_args(func, argdict) and not invalid_args(func, argdict)
(This is good only as far as python's arg parsing. Any runtime checks for invalid values in kwargs
obviously can't be detected.)
Getting the keyword arguments actually passed to a Python method
I was inspired by lost-theory's decorator goodness, and after playing about with it for a bit came up with this:
def actual_kwargs():
"""
Decorator that provides the wrapped function with an attribute 'actual_kwargs'
containing just those keyword arguments actually passed in to the function.
"""
def decorator(function):
def inner(*args, **kwargs):
inner.actual_kwargs = kwargs
return function(*args, **kwargs)
return inner
return decorator
if __name__ == "__main__":
@actual_kwargs()
def func(msg, a=None, b=False, c='', d=0):
print msg
for arg, val in sorted(func.actual_kwargs.iteritems()):
print ' %s: %s' % (arg, val)
func("I'm only passing a", a='a')
func("Here's b and c", b=True, c='c')
func("All defaults", a=None, b=False, c='', d=0)
func("Nothin'")
try:
func("Invalid kwarg", e="bogon")
except TypeError, err:
print 'Invalid kwarg\n %s' % err
Which prints this:
I'm only passing a
a: a
Here's b and c
b: True
c: c
All defaults
a: None
b: False
c:
d: 0
Nothin'
Invalid kwarg
func() got an unexpected keyword argument 'e'
I'm happy with this. A more flexible approach is to pass the name of the attribute you want to use to the decorator, instead of hard-coding it to 'actual_kwargs', but this is the simplest approach that illustrates the solution.
Mmm, Python is tasty.
How to get keyword arguments for a function
You can use inspect.getargspec()
to get the arguments a function expects.
>>> inspect.getargspec(test)
ArgSpec(args=['arg1', 'arg2', 'arg3'], varargs=None, keywords=None,
defaults=(None,))
As you can see the keywords
attribute is None
as any argument can be passed as a kwarg; it would contain the name of the **kwargs
argument if one existed.
To get a dict mapping the argument names to default values you can use this code with as
being the ArgSpec returned by inspect.getargspec()
:
defaults = dict(zip(*[reversed(l) for l in (as.args, as.defaults or [])]))
Get Keyword Arguments for Function, Python
Do you want something like this:
>>> def func(x,y,z,a=1,b=2,c=3):
pass
>>> func.func_code.co_varnames[-len(func.func_defaults):]
('a', 'b', 'c')
How can I pass keyword arguments as parameters to a function?
Looks like you're looking for the *
and **
notations:
def outer_func(*args, **kwargs):
inner_func(*args, **kwargs)
Then you can do outer_func(1, 2, 3, a='x', b='y')
, and outer_func
will call inner_func(1, 2, 3, a='x', b='y')
.
If you only want to allow keyword arguments, drop the *args
.
In a function definition, a parameter marked with *
receives a tuple of all positional arguments that didn't correspond to other declared parameters, and an argument marked with **
receives a dict of all keyword arguments that didn't correspond to other declared parameters.
In a function call, prefixing a sequence (or other iterable) argument with *
unpacks it into separate positional arguments, and prefixing a mapping argument with **
unpacks it into separate keyword arguments.
What is the purpose and use of **kwargs?
You can use **kwargs
to let your functions take an arbitrary number of keyword arguments ("kwargs" means "keyword arguments"):
>>> def print_keyword_args(**kwargs):
... # kwargs is a dict of the keyword args passed to the function
... for key, value in kwargs.iteritems():
... print "%s = %s" % (key, value)
...
>>> print_keyword_args(first_name="John", last_name="Doe")
first_name = John
last_name = Doe
You can also use the **kwargs
syntax when calling functions by constructing a dictionary of keyword arguments and passing it to your function:
>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith
The Python Tutorial contains a good explanation of how it works, along with some nice examples.
Python 3 update
For Python 3, instead of iteritems()
, use items()
Passing a list of kwargs?
Yes. You do it like this:
def method(**kwargs):
print kwargs
keywords = {'keyword1': 'foo', 'keyword2': 'bar'}
method(keyword1='foo', keyword2='bar')
method(**keywords)
Running this in Python confirms these produce identical results:
{'keyword2': 'bar', 'keyword1': 'foo'}
{'keyword2': 'bar', 'keyword1': 'foo'}
Passing a dictionary to a function as keyword parameters
Figured it out for myself in the end. It is simple, I was just missing the ** operator to unpack the dictionary
So my example becomes:
d = dict(p1=1, p2=2)
def f2(p1,p2):
print p1, p2
f2(**d)
How to check which arguments a function/method takes?
You can use inspect.getargspec()
to see what arguments are accepted, and any default values for keyword arguments.
Demo:
>>> def foo(bar, baz, spam='eggs', **kw): pass
...
>>> import inspect
>>> inspect.getargspec(foo)
ArgSpec(args=['bar', 'baz', 'spam'], varargs=None, keywords='kw', defaults=('eggs',))
>>> inspect.getargspec(foo).args
['bar', 'baz', 'spam']
In Python 3, you want to use inspect.getfullargspec()
as this method supports new Python 3 function argument features:
>>> def foo(bar: str, baz: list, spam: str = 'eggs', *, monty: str = 'python', **kw) -> None: pass
...
>>> import inspect
>>> inspect.getfullargspec(foo)
FullArgSpec(args=['bar', 'baz', 'spam'], varargs=None, varkw='kw', defaults=('eggs',), kwonlyargs=['monty'], kwonlydefaults={'monty': 'python'}, annotations={'baz': <class 'list'>, 'return': None, 'spam': <class 'str'>, 'monty': <class 'str'>, 'bar': <class 'str'>})
inspect.getargspec()
should be considered deprecated in Python 3.
Python 3.4 adds the inspect.Signature()
object:
>>> inspect.signature(foo)
<inspect.Signature object at 0x100bda588>
>>> str(inspect.signature(foo))
"(bar:str, baz:list, spam:str='eggs', *, monty:str='python', **kw) -> None"
>>> inspect.signature(foo).parameters
mappingproxy(OrderedDict([('bar', <Parameter at 0x100bd67c8 'bar'>), ('baz', <Parameter at 0x100bd6ea8 'baz'>), ('spam', <Parameter at 0x100bd69f8 'spam'>), ('monty', <Parameter at 0x100bd6c28 'monty'>), ('kw', <Parameter at 0x100bd6548 'kw'>)]))
and many more interesting options to play with signatures.
Related Topics
How to Implement a Minimal Server for Ajax in Python
About the Pil Error -- Ioerror: Decoder Zip Not Available
Python Command Line Input in a Process
Run Powershell Function from Python Script
Transform "List of Tuples" into a Flat List or a Matrix
Filtering a List Based on a List of Booleans
"Private" (Implementation) Class in Python
Importerror: No Module Named Tensorflow
Checking Odd/Even Numbers and Changing Outputs on Number Size
How to Convert a Scikit-Learn Dataset to a Pandas Dataset
What Exactly Is the Point of Memoryview in Python
Search by Objectid in Mongodb with Pymongo
Populate a Pandas Sparsedataframe from a Scipy Sparse Matrix
How to Find the First Key in a Dictionary
How to Get Value from Form Field in Django Framework