In a similar way to using varargs in C or C++:
fn(a, b)
fn(a, b, c, d, ...)
Adding to unwinds post:
You can send multiple key-value args too.
def myfunc(**kwargs):
# kwargs is a dictionary.
for k,v in kwargs.iteritems():
print "%s = %s" % (k, v)
myfunc(abc=123, efh=456)
# abc = 123
# efh = 456
And you can mix the two:
def myfunc2(*args, **kwargs):
for a in args:
print a
for k,v in kwargs.iteritems():
print "%s = %s" % (k, v)
myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123
They must be both declared and called in that order, that is the function signature needs to be *args, **kwargs, and called in that order.
def f(dic):
if 'a' in dic:
print dic['a'],
pass
else: print 'None',
if 'b' in dic:
print dic['b'],
pass
else: print 'None',
if 'c' in dic:
print dic['c'],
pass
else: print 'None',
print
pass
f({})
f({'a':20,
'c':30})
f({'a':20,
'c':30,
'b':'red'})
____________
the above code will output
None None None
20 None 30
20 red 30
This is as good as passing variable arguments by means of a dictionary
Yes. You can use *args
as a non-keyword argument. You will then be able to pass any number of arguments.
def manyArgs(*arg):
print "I was called with", len(arg), "arguments:", arg
>>> manyArgs(1)
I was called with 1 arguments: (1,)
>>> manyArgs(1, 2, 3)
I was called with 3 arguments: (1, 2, 3)
As you can see, Python will unpack the arguments as a single tuple with all the arguments.
For keyword arguments you need to accept those as a separate actual argument, as shown in Skurmedel's answer.
Another way to go about it, besides the nice answers already mentioned, depends upon the fact that you can pass optional named arguments by position. For example,
def f(x,y=None):
print(x)
if y is not None:
print(y)
Yields
In [11]: f(1,2)
1
2
In [12]: f(1)
1
If I may, Skurmedel's code is for python 2; to adapt it to python 3, change iteritems
to items
and add parenthesis to print
. That could prevent beginners like me to bump into:
AttributeError: 'dict' object has no attribute 'iteritems'
and search elsewhere (e.g. Error “ 'dict' object has no attribute 'iteritems' ” when trying to use NetworkX's write_shp()) why this is happening.
def myfunc(**kwargs):
for k,v in kwargs.items():
print("%s = %s" % (k, v))
myfunc(abc=123, efh=456)
# abc = 123
# efh = 456
and:
def myfunc2(*args, **kwargs):
for a in args:
print(a)
for k,v in kwargs.items():
print("%s = %s" % (k, v))
myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123
Adding to the other excellent posts.
Sometimes you don't want to specify the number of arguments and want to use keys for them (the compiler will complain if one argument passed in a dictionary is not used in the method).
def manyArgs1(args):
print args.a, args.b #note args.c is not used here
def manyArgs2(args):
print args.c #note args.b and .c are not used here
class Args: pass
args = Args()
args.a = 1
args.b = 2
args.c = 3
manyArgs1(args) #outputs 1 2
manyArgs2(args) #outputs 3
Then you can do things like
myfuns = [manyArgs1, manyArgs2]
for fun in myfuns:
fun(args)