+ 9

Problem with global/local variables

Problem expalianed in codes below https://code.sololearn.com/cc5bf11B7rkt/?ref=app https://code.sololearn.com/coxC6VujrExq/?ref=app

28th Nov 2020, 1:38 PM
Yohanan
28 Answers
+ 6
Read your code from right to left, this is how Python reads it. 1 + a = a The fact that you have a=1 outside the function is irrelevant, Python sees you setting the variable a=a+1... but what is a? You have overwritten a=1 with a=a+1.. therefore a is not defined
28th Nov 2020, 2:47 PM
Steven M
Steven M - avatar
+ 13
You can read global variables from within a function. But, to modify global variables, you'll need to use the global keyword as below: a = 1 def func(): global a a = a + 5 func() ---- TBH... Variable scoping in Python feels like it was patched on like an afterthought resulting in awkward, inconsistent situations like this. But then it gets justified as being Pythonic rather than as a limitation in the language design.
28th Nov 2020, 2:53 PM
David Carroll
David Carroll - avatar
+ 9
So a couple of things, you can return a variable in your function, that should solve it, or you can rename your local variable to something else other than "a". Python treats variables as local variables unless specifically declared, there are numerous reasons for this, but the main one is for security... Global variables are bad practice and should be avoided. In both your examples, "a" is a global & a local variable. This is confusing to Python, so, as a result it is treated as a local variable. The problem is you are using "a" to define "a" and "a" has NOT been properly defined in local scope. I hope this helps.
28th Nov 2020, 2:12 PM
Steven M
Steven M - avatar
+ 9
[Part 1 of 5] Exploring Limitiations of Python's Language Design Decisions: Steven M: I believe what you're saying regarding: a = a + 5 ... is that {a} is being locally declared and then attempting to access that local variable before it has been assigned a local value - which I agree. Alternatively, replacing the line above with: a = 5 ... would apply to a local {a} while replacing with: b = a + 5 ... would read from global {a}. While Python allows reading global {a} by default, assignment requires explicitly declaring the global variable into the local scope. This is where Python, IMO, has issues. The reason for this mixed behavior is that the BDFL decided to make it such that global variables can be read from within functions, but must be explicitly declared using the global keyword for assignments. This is probably the best option for a language limited by its design decisions - in particular, its commitment to exist without variable declarations or explicitly ending blocks.
28th Nov 2020, 5:55 PM
David Carroll
David Carroll - avatar
+ 8
[Part 3 of 5] Exploring Limitiations of Python's Language Design Decisions: ** Why not make it so globals can ONLY be accessed and assigned when explicitly using the global [var] keyword? ** The reason is because there aren't any differences in the scope accessing rules for functions, classes, and variables declared in global. If accessing variable {a} required explicitly using the global keyword, then so would all functions and classes declared in global. Consider how ridiculous the following would be: def a(): pass def b(): pass def c(): pass def d(): global a, b, c a() b() c() Imagine the various real life scenarios where any functions used within a function had to be explicitly declared using the global keyword.
28th Nov 2020, 5:55 PM
David Carroll
David Carroll - avatar
+ 7
[Part 2 of 5] Exploring Limitiations of Python's Language Design Decisions: Let's examine further what I mean by limitations in Python's language design decisions with the following questions: ** Why not make it so globals can be accessed and assigned without explicitly using the global [var] keyword? ** Without variable declarations, there would be no way to implicitly know whether or not a name assignment in a function was meant for the global or local scope. Example: a = 1 def func() a = 2 func() print(a) #Should this be 1 or 2? Current rules force this to be 1 so that variable {a} can exist locally in func(). This is a good thing. But, it's also inconsistent with the default rules for reading / accessing global vars. So...
28th Nov 2020, 5:55 PM
David Carroll
David Carroll - avatar
+ 7
[Part 4 of 5] Exploring Limitiations of Python's Language Design Decisions: ** Is the global keyword the only way to access global variables from within a function? ** Nope. Technically... the following could be done: a = 1 def func(): g = globals() g['a'] = 2 g['b'] = 5 # For kicks and giggles... func() #------ print(f"a: {a}") # outputs 2 instead of 1 #------ print(f"b: {b}") # outputs 5 Yeah... that just happened... Variable {b} now exists without any formal declaration. It's essentially updating a hash table (er dictionary object).
28th Nov 2020, 5:55 PM
David Carroll
David Carroll - avatar
+ 7
[Part 5 of 5] Exploring Limitiations of Python's Language Design Decisions: ** What other Scoping Limitations result from Python's Language Design Decisons? ** Well... it was a pain for the BDFL and his Pythonistas to figure out the best way to support both global and local scopes to begin with (and later nonlocal scope). But, they really haven't been able to figure out how to overcome the ambiguity of enclosed variables from within lambdas. So... basically, a closure with enclosed variables declared in the outer function is read only from within lambdas. This pretty much makes lambda closures useless in Python. Futhermore, they haven't figured out a way to introduce block scope variables. This would require an explicit delimiter for closing a block - which is very anti-Pythonic. It's just easier to call this unPythonic and dismiss the use cases for block scope variables as overcomplicating the function, and move on. Anyway, these are all gross limitations based on the language design decisions... IMHO.
28th Nov 2020, 6:15 PM
David Carroll
David Carroll - avatar
+ 5
For those who have already read my 5 Part responses, I've drastically cleaned up [Part 1 of 5] and made some minor updates to the other 4 parts. I think it's all much clearer now. Apologies for any confusion that might have occurred. It should all flow better now.
28th Nov 2020, 9:23 PM
David Carroll
David Carroll - avatar
29th Nov 2020, 12:03 PM
Emiliano Passarello
Emiliano Passarello - avatar
+ 1
Is because when python first sees the line 'a = a + 1', it reads LHS first, and creates a local variable 'a', and then when it reads the RHS, it finds the variable 'a', looks for the value of 'a' in local scope, and when it finds that 'a' hasn't been assigned any value in local scope, it throws an UnboundLocalError?
28th Nov 2020, 2:48 PM
Yohanan
+ 1
Ok, i get if now. When python sees a = a + 1, it overwrites a=1. Right?
28th Nov 2020, 2:53 PM
Yohanan
+ 1
Yohanan yes exactly, it is similar to using a word to define a word. Its like if you friends asks you what "dog" means and you say "dog is dog" ... that doesn't help your friend understand the word "dog" just like with Python, it can become confused too so it is best to use another variable or return a value from one of the functions and pass it as an argument to the others
28th Nov 2020, 2:56 PM
Steven M
Steven M - avatar
+ 1
Yeah LEGB are the steps Python uses, the link below explains it really well. https://realpython.com/python-scope-legb-rule/
28th Nov 2020, 3:21 PM
Steven M
Steven M - avatar
+ 1
Steven M thanks
28th Nov 2020, 3:23 PM
Yohanan
+ 1
Something like this would work too https://code.sololearn.com/cOrsITvmnpD9/?ref=app
28th Nov 2020, 3:24 PM
Steven M
Steven M - avatar
+ 1
David Carroll thank you so much. I didn't know about the globals function before. Its pretty intetresting.
28th Nov 2020, 6:41 PM
Yohanan
+ 1
I suggest the OS, though I could be wrong.
29th Nov 2020, 9:49 AM
Zifa Nyirenda
Zifa Nyirenda - avatar
+ 1
llay *_* Please do not create spam threads or add spammy comments to an existing thread. Both are seen as negative behavior. Thanks and happy coding https://code.sololearn.com/Wv5gTHy1N6Ji/?ref=app
1st Dec 2020, 1:14 AM
BroFar
BroFar - avatar