Created
June 18, 2014 13:02
-
-
Save deemson/8efabf56d67623ead804 to your computer and use it in GitHub Desktop.
Demo of late binding in Python's closures and how to avoid it when needed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Demo of late binding in Python's closures and how to avoid it when needed | |
functions = [] | |
for n in [1, 2, 3]: | |
def func(x): | |
return n*x | |
functions.append(func) | |
# You would expect this to print [2, 4, 6] | |
print( | |
'calling a list of bad closures and output is: {}' | |
.format(str([function(2) for function in functions])) | |
) | |
# But it will print [6, 6, 6] actually, because Python binds late the n | |
# variable, after the execution of the for loop above when n equals 3 | |
# To avoid this behavior one of the options you can use is default arguments: | |
functions = [] | |
for n in [1, 2, 3]: | |
def func(x, n=n): | |
return n*x | |
functions.append(func) | |
# This will print [2, 4, 6] | |
print( | |
'calling a list of functions with default arguments and output is: {}' | |
.format(str([function(2) for function in functions])) | |
) | |
# I don't like this solution though as it's rather hacky | |
# The solution I would use in this case would be to use functools.partial: | |
from functools import partial | |
functions = [] | |
for n in [1, 2, 3]: | |
def func(n, x): | |
return n*x | |
functions.append(partial(func, n)) | |
print( | |
'calling a list of partialy built functions and output is: {}' | |
.format(str([function(2) for function in functions])) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment