Pythonの坑
Python closures and late binding
A closure occurs when a function has access to a local variable from an enclosing scope that has finished its execution.
def make_printer(msg): def printer(): print msg return printer
We can see that the printer()
function depends on the variable msg
which is defined outside the scope of it’s function.
Late binding and bad side-effects
Python’s closures are late binding. This means that the values of variables used in closures are looked up at the time the inner function is called.
def multipliers(): return [lambda x : i*x for i in range(4)] print [m(2) for m in multipliers()] # [6, 6, 6, 6]
Then we expect the output of the print statement to be [0, 2, 4, 6]
based on the element-wise operation [0*2, 1*2, 2*2, 3*2]
. However, [3*2, 3*2, 3*2, 3*2] = [6, 6, 6, 6]
is what is actually return. That is because i
is not passed to the the lambda function until the loop for i in range(4)
has been evaluated.
def multipliers(): return [lambda x, i=i : i * x for i in range(4)] print [m(2) for m in multipliers()] # [0, 2, 4, 6]
附:
python十坑(英文)
python十六坑(中文)
诸神对凡人心生艳羡,厌倦天堂。