+ 2

locals and globals in function

Hi I'm wondering, I've seen this question in challenges, which went something like this: def bar(): x = 0 def foo(): print('x' in locals(), 'x' in globals()) foo() bar() The answer was clear to me.. Well it was until I started to play with this code: def bar2(): x = 0 def foo2(): print(x in locals(), x in globals()) foo2() bar2() gave the same answers and it was still clear, but than this happend: def bar3(): x = 0 def foo3(): print('x' in locals(), 'x' in globals(), x in locals(), x in globals()) foo3() bar3() why does the "'x' in locals()" return True? I thought, that 'x' is a string which quite obviously is not present in the foo() function in every option, and so is the x variable, which is only in the scope of bar function.. So every option should be False - what am I missing?

3rd Jul 2021, 4:02 PM
Zither🇵🇱🇺🇦
Zither🇵🇱🇺🇦 - avatar
12 Answers
+ 3
because in bar::foo you doesn't use it, while you use in both others (by testing if x in locals() and in globals()) ^^ add print(x) in bar::foo, and you will see it in local dict ;P
3rd Jul 2021, 5:21 PM
visph
visph - avatar
+ 2
no idea of how the behavior is implemented under the hood ;P seems that until parent scope variable is not accessed, local dict is not populated... don't know how python handle difference between 'nonlocal' declared variable (read/write access) and 'readonly' undeclared parent scope variable ^^
3rd Jul 2021, 5:36 PM
visph
visph - avatar
+ 2
Thanks for the answers. So again, so I'll be sure that I understand it correctly - the variable x is not in the scope of foo until it's used and you use it while you check if it's in the scope by printing x in locals(). Right?
3rd Jul 2021, 7:13 PM
Zither🇵🇱🇺🇦
Zither🇵🇱🇺🇦 - avatar
+ 2
visph i had to read it twice.. :D but I think I get it, thanks once again :)
3rd Jul 2021, 7:30 PM
Zither🇵🇱🇺🇦
Zither🇵🇱🇺🇦 - avatar
+ 2
lazy evaluation as long as not accessed...bo reason to occupy memory space.
3rd Jul 2021, 8:36 PM
Oma Falk
Oma Falk - avatar
+ 2
Yeah, it's kinda tricky. I can't wait until I'll have an opportunity to try to explain it to somebody else ;)
4th Jul 2021, 5:16 PM
Zither🇵🇱🇺🇦
Zither🇵🇱🇺🇦 - avatar
+ 1
locals() and globals() return dict with var names as keys... so 'x' in dict is the correct way to test if variable 'x' is in it... x un dict test if value of x is in dict ^^ scope of 'bar' is inside scope of 'foo'... so local scope of 'bar' contains local scope of 'foo'... until local variable are not accessed to be written, there are accessible to be read... to make a global variable writable in a local scope use 'global' var declaration to make a parent local variable writable in a nested local scope use 'nonlocal' var declaration
3rd Jul 2021, 4:58 PM
visph
visph - avatar
+ 1
Visph, In the code, why variable <x> isn't listed in locals() in bar::foo? where <x> is listed in locals() for bar2::foo2 and bar3::foo3 https://code.sololearn.com/cDbVRUkC78qa/?ref=app
3rd Jul 2021, 5:16 PM
Ipang
+ 1
Visph, Does that mean <x> a nonlocal for bar::foo becomes a local when it is accessed? or a local is created and initialized by nonlocal value?
3rd Jul 2021, 5:30 PM
Ipang
+ 1
not exactly: you check if it is in the scope by using its name (string), so you don't use it... and it's not in the local scope. if you use it (by doing print(x) or by doing x in locals() or anything else, then the locals dict is populated with it and 'x' in locals() will return True, but x in locals() will return False until x contains a local variable name ^^
3rd Jul 2021, 7:20 PM
visph
visph - avatar
+ 1
Oma Falk I forgot yesterday - danke schön ;)
4th Jul 2021, 4:48 PM
Zither🇵🇱🇺🇦
Zither🇵🇱🇺🇦 - avatar
+ 1
Zither gerne...das war ein spannender Versuch
4th Jul 2021, 5:12 PM
Oma Falk
Oma Falk - avatar