The *args
and **kwargs
is a common idiom to allow arbitrary number of arguments to functions as described in the section more on defining functions in the Python documentation.
The *args
will give you all function parameters as a tuple:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1,2,3)
# 1
# 2
# 3
The **kwargs
will give you all
keyword arguments except for those corresponding to a formal parameter as a dictionary.
def bar(**kwargs):
for a in kwargs:
print(a, kwargs[a])
bar(name='one', age=27)
# name one
# age 27
Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:
def foo(kind, *args, **kwargs):
pass
It is also possible to use this the other way around:
def foo(a, b, c):
print(a, b, c)
obj = {'b':10, 'c':'lee'}
foo(100,**obj)
# 100 10 lee
Another usage of the *l
idiom is to unpack argument lists when calling a function.
def foo(bar, lee):
print(bar, lee)
l = [1,2]
foo(*l)
# 1 2
In Python 3 it is possible to use *l
on the left side of an assignment (Extended Iterable Unpacking), though it gives a list instead of a tuple in this context:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Also Python 3 adds new semantic (refer PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
Such function accepts only 3 positional arguments, and everything after *
can only be passed as keyword arguments.
Note:
- A Python
dict
, semantically used for keyword argument passing, are arbitrarily ordered. However, in Python 3.6, keyword arguments are guaranteed to remember insertion order.
- "The order of elements in
**kwargs
now corresponds to the order in which keyword arguments were passed to the function." - What’s New In Python 3.6
- In fact, all dicts in CPython 3.6 will remember insertion order as an implementation detail, this becomes standard in Python 3.7.
The original answer below was written in 2008. Since then, Python 3.10 (2021) introduced the match
-case
statement which provides a first-class implementation of a "switch" for Python. For example:
def f(x):
match x:
case 'a':
return 1
case 'b':
return 2
case _:
return 0 # 0 is the default case if x is not found
The match
-case
statement is considerably more powerful than this simple example.
You could use a dictionary:
def f(x):
return {
'a': 1,
'b': 2,
}[x]
Best Answer
I believe this has already been answered by other users before me, so I only add it for the sake of completeness: the
with
statement simplifies exception handling by encapsulating common preparation and cleanup tasks in so-called context managers. More details can be found in PEP 343. For instance, theopen
statement is a context manager in itself, which lets you open a file, keep it open as long as the execution is in the context of thewith
statement where you used it, and close it as soon as you leave the context, no matter whether you have left it because of an exception or during regular control flow. Thewith
statement can thus be used in ways similar to the RAII pattern in C++: some resource is acquired by thewith
statement and released when you leave thewith
context.Some examples are: opening files using
with open(filename) as fp:
, acquiring locks usingwith lock:
(wherelock
is an instance ofthreading.Lock
). You can also construct your own context managers using thecontextmanager
decorator fromcontextlib
. For instance, I often use this when I have to change the current directory temporarily and then return to where I was:Here's another example that temporarily redirects
sys.stdin
,sys.stdout
andsys.stderr
to some other file handle and restores them later:And finally, another example that creates a temporary folder and cleans it up when leaving the context: