@@ -5,12 +5,14 @@ For the most part, Python aims to be a clean and consistent language that
55avoid surprises, but there are a few cases where newcomers to the language
66often get tripped up.
77
8- Some of these are intentional but surprising. Some could arguably be considered
9- language warts. In general though, what follows is a collection of potentially
10- tricky behavior that might seem strange at first glance, but is generally
11- sensible despite surprise after learning of its existence .
8+ Some of these are intentional but potentially surprising. Some could arguably
9+ be considered language warts. In general though, what follows is a collection
10+ of potentially tricky behavior that might seem strange at first glance, but is
11+ generally sensible once you're aware of the underlying cause for the surprise .
1212
1313
14+ .. _default_args :
15+
1416Mutable Default Arguments
1517-------------------------
1618
@@ -59,3 +61,64 @@ signal that no argument was provided (``None`` is often a good choice).
5961Sometimes you specifically can "exploit" (read: use as intended) this behavior
6062to maintain state between calls of a function. This is often done when writing
6163a caching function.
64+
65+
66+ Late Binding Closures
67+ ---------------------
68+
69+ Another common source of confusion is the way Python binds its variables in
70+ closures (or in the surrounding global scope).
71+
72+ **What You Wrote **
73+
74+ .. code-block :: python
75+
76+ def create_adders ():
77+ return [lambda x : i * x for i in range (5 )]
78+
79+ **What You Might Have Expected to Happen **
80+
81+ A list containing five functions that each have their own closed-over ``i ``
82+ variable that multiplies their argument.
83+
84+ **What Does Happen **
85+
86+ Five functions are created, but all of them just multiply ``x `` by 4.
87+
88+ Python's closures are *late binding *. This means that names within closures are
89+ looked up at the time the inner function is *called *.
90+
91+ Here, whenever *any * of the returned functions are called, the value of ``i ``
92+ is looked up in the surrounding scope at call time, when by then the loop has
93+ completed and ``i `` is left with its final value of 4.
94+
95+ What's particularly nasty about this gotcha is the seemingly prevalent
96+ misinformation that this has something to do with ``lambda ``\s in Python.
97+ Functions created with a ``lambda `` expression are in no way special, and in
98+ fact the same exact behavior is exhibited by just using an ordinary ``def ``:
99+
100+ .. code-block :: python
101+
102+ def create_adders ():
103+ for i in range (5 ):
104+ def adder (x ):
105+ return i * x
106+ yield adder
107+
108+ **What You Should Do Instead **
109+
110+ Well. Here the general solution is arguably a bit of a hack. Due to Python's
111+ afformentioned behavior concerning evaluating default arguments to functions
112+ (see :ref: `default_args `), you can create a closure that binds immediately to
113+ its arguments by using a default arg like so:
114+
115+ .. code-block :: python
116+
117+ def create_adders ():
118+ return [lambda x , i = i : i * x for i in range (5 )]
119+
120+ **When the Gotcha Isn't a Gotcha **
121+
122+ When you want your closures to behave this way. Late binding is good in lots of
123+ situations. Looping to create unique functions is unfortunately a case where
124+ they can cause hiccups.
0 commit comments