Reputation: 2202
What is happening under the hood with this code? pythontutor isn't helpful for this.
Some questions: why can ok_then() "see" the variable sure.d? What's the point of naming the variable sure.d if every function in this module can see it?
def ok_then():
print(ok_then.c)
print(sure.d)
def sure():
pass
def set_vals(c,d):
ok_then.c = c
sure.d = d
>>> set_vals(3, 4)
>>> ok_then
3
4
Finally, why does this error? Something is happening with the ok_then.c and sure.d from a scope perspective but I'm not clear exactly what.
def ok_then():
print(a)
print(b)
def sure():
pass
def set_vals(c,d):
a = c
b = d
>>> set_vals(3,4)
>>> ok_then()
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
ok_then()
File "C:/Users/test_set_vals.py", line 2, in ok_then
print(a)
NameError: name 'a' is not defined
Upvotes: 2
Views: 80
Reputation: 71
In short, because everything, including function definitions, are objects. And secondly, scope.
In your first example, you define three functions ok_then, sure and set_vals. In set_vals you then assign a value to attribute "c" of the function ok_then, and a value to attribute "d" of the function sure. This is an odd thing to do, but it's allowed in Python. It works because you have defined ok_then and sure and they're in the current module scope.
In your second example, ok_then tries to reference variables "a" and "b". They don't exist in that scope. The only scope they exist is within the function set_vals.
Note that calling set_vals.a is NOT a way to access a variable inside the scope of the function. You probably want to create a class for that type of behavior instead.
Upvotes: 3
Reputation: 1754
The difference in the two examples is that in the first one c
and d
are attributes of the objects which are the functions ok_then
and sure
. Pretty much like this:
class CDHolder:
pass # empty class
cdholder = CDHolder() # cdholder is now an object
cdholder.c = 3 # the attribute "c" is now 3
function printC():
print( cdholder.c )
printC()
This will print 3 because printC can of course "see" cdholder and therefore will be able to access it's attributes.
In the second example a
and b
are local variables. They do not exist outside of set_vals
and cannot be accessed. Also they only exist for as long as set_vals is run, after that they "go out of scope" (are deleted).
Upvotes: 2
Reputation: 737
I Think the scope is okay. In the first example you define methods (ok_then and sure). Those are in the module scope. After hat you set variables "into" those methods. The methods are still in the module scope. So every method in the same scope (module) can read them.
In the other example you define variables in the scope of the method "set_val". So all other methods can't read them.
Upvotes: 1