I learned Matlab before I learned Python, and some of the patterns one learns in one language are hard to forget when you learn a new one. Scoping is a common area of misunderstanding between the two languages.
I’m using Octave in these examples, but the language is the same in this respect. Consider the following snipped of code:
> a = 1; > b = 2; > f = @(x) a*x + b; > f(2) ans = 4 > a = 0; > b = 0; > f(2) ans = 4
What we see here is that Matlab/Octave binds the values of the variables to the function defined in line 3 at the time of definition. This means changing a and b later doesn’t change f. This is useful when functions are passed back and forth – you can build a function in one place and use it later without fearing that changing local variables will change the behaviour of the function. Let’s do the same thing in Python (the function definition below is completely equivalent to f = lambda x: a*x + b):
a = 1
b = 2
def f(x):
return a*x + b
print f(2)
a = 0
b = 0
print f(2)
Output:
4 0
If you are used to the Matlab way, this result may be counter-intuitive, but I remember teaching students to program in Matlab, and in fact this was a common problem. Remembering that the variables are captured in Matlab was hard for some people, who expected Python’s behaviour.
It is worth noticing that in the Python version, the names bound to f are not simply evaluated in whatever scope they are passed to, as can be seen if we define a new function (which will have its own namespace):
def g():
a = 5
b = 6
return f(2)
print g()
Output:
0
The rule in Python is therefore that the names in functions are resolved when the function was defined, but that the values will only be obtained at the time of execution of the function. Because g has its own namespace, that a and b are different from the one in the global namespace.
In fact, it is possible to think of what is happening in a similar way if you remember how names and values work in Python. I highly recommend this article for a good overview of how this works. I have also found this Online Python Tutor very helpful to visualise how the name-value relationship works.
Leave a Reply