Beginners of Python often encounter problems in terms of scope.
Generally, when we define a global variable (well, I say this is because the need to explain -- global variables are not good), we can use a function to access them to be understood by Python:
bar = 42def foo(): print bar
Here, we use the global variable bar in the foo function, and it can run normally as expected:
>>> foo()42
This is cool. Generally, we want to use this feature in all the code. If it is used in the following example, it can still run normally:
bar = [42]def foo(): bar.append(0)foo() >>> print bar[42, 0]
However, if we change the bar:
>>> bar = 42... def foo():... bar = 0... foo()... print bar42
We can see that the foo function runs well without throwing an exception, but when we print the bar value, we will find that its value is still 42. This is because bar = 0 is the code line. It does not change the value of the global variable bar. Instead, it creates a local variable named bar and its value is 0. This is a hard-to-find bug, which makes it very painful for new users who do not really understand the Python scope. To understand how Python handles local and global variables, we can see a rare but confusing error, after printing the bar value, we define a local variable named bar:
bar = 42def foo(): print bar bar = 0
In this way, there should be no errors in writing, right? We have defined variables with the same name after printing the value, so this should not be affected (Python is an interpreted language after all). Is that true?
Error
How is this possible? Okay, there are two errors. The first point is about Python. As an interpreted language (cool, we all agree to this), it is executed in one line. In fact, Python declares and executes a declaration. To make you feel a little bit about what I want to say, open your favorite shell and enter the following code:
def foo():
Press enter. As you can see, shell does not output any output, but is waiting for you to continue the definition of the function. Shell will continue until you stop defining the function. This is because the definition function is a declaration. Well, this is a hybrid declaration that contains some other statements, but it is still a declaration. Until the function is called, the content in the function will not be executed. What is actually executed is that a function-type object is created.
This leads us to focus on the second point. The dynamic nature of Python and its explanatory features make us believe that when the print bar line is executed, python will first look for the variable bar in the local scope and then look for the variable in the global scope. But what actually happens is that the local scope is not completely dynamic. When the def statement is executed, Python statically obtains information from the local scope of the function. When bar = 0 (this line of code is not executed, but when the Python interpreter reads this line of code ), it adds the 'bar' variable to the partial Variable list of the foo function. When the foo function is executed and Python is about to execute the print bar line, it will look for this variable in a local scope, because the process is static, python knows that this variable has not been assigned a value, and this variable has no value, so an exception is thrown.
You may ask: Why can't I throw this exception when declaring a function? Python knows that the bar variable is referenced before the value assignment. The answer to this question is that Python cannot know whether the bar of this local variable is assigned a value. Take a look at the following example:
bar = 42def foo(baz): if baz > 0: print bar bar = 0
Python plays a subtle game between dynamic and static. The only thing it knows is that bar is assigned a value, but it does not know whether the exception is referenced before the assignment until it actually occurs. Well, to be honest, it doesn't even know whether the variable is assigned a value!
bar = 42def foo(): print bar if False: bar = 0 >>> foo()Traceback (most recent call last): File "<pyshell#17>", line 1, in <module> foo() File "<pyshell#16>", line 3, in foo print barUnboundLocalError: local variable 'bar' referenced before assignment
We can see in the above Code that although we can clearly know as an intelligent creature that we will not assign values to bar. Python ignores the fact but still declares the local variable bar.
I have already said this long enough. What we need is a solution. I will provide two solutions here.
>>> bar = 42... def foo():... global bar... print bar... bar = 0...... foo()42>>> bar0
The first is to use the global keyword. This is self-evident. This will let Python know that bar is a global variable rather than a local variable.
The second method is more recommended, that is, do not use global variables. I have never used the global keyword in a lot of Python development work. You just need to know how to use it, but try to avoid using it. If you want to save the value used in the code from the beginning to the end, define it as a class attribute. If you use this method, you do not need to use global. When you use this value, you can access it through the class attribute:
>>> class Baz(object):... bar = 42...... def foo():... print Baz.bar # global... bar = 0 # local... Baz.bar = 8 # global... print bar...... foo()... print Baz.bar4208