Novice Python often makes mistakes

Source: Internet
Author: User

Novice Python often makes mistakes (part two)

Forwarded from: http://blog.jobbole.com/43826/

Scope

In this article, let's focus on the scope where Python is misused. Usually, when we define a global variable (well, I'm saying this because the need for explanation--the global variables are bad), we use a function to access them that can be understood by Python:

123 bar = 42def foo():    print bar

Here we use the global variable bar in the Foo function, and it works as expected:

12 >>> foo()42

This is cool. In general, after we use this feature, we want to use it in all the code. If the following example is used, it will work:

1234567 bar =[42]def foo():    bar.append(0)foo() >>> printbar[42, 0]

But what if we change the bar a bit:

123456 < Code class= "Python plain" >>>> bar =   42 def  foo (): ...     bar =  0 ... Foo () print  bar 42

We can see that the Foo function works well and does not throw an exception, but when we print the value of bar we find that its value is still 42. The reason for this is that bar=0 this line of code, which does not change the value of the global variable bar, but instead creates a local variable whose name is also called bar and its value is 0. This is a hard-to-find bug, which makes it very painful for beginners who don't really understand the python scope. To understand how Python handles local and global variables, let's look at a more rare, but potentially confusing, error, where we define a local variable called bar after we print the bar value:

1234 bar =42def foo():    print bar    bar =0

It's not going to go wrong, is it? We define a variable with the same name after the value is printed, so this should not be affected (Python is, after all, an interpreted language), is that really the case?

Something went wrong.

How is that possible? OK, here are two mistakes. The 1th is about Python, as an interpreted language (very cool, which we all agree on), and is executed one line at a a-line. In fact, Python is a declaration of a declaration executed. To make you feel a little bit about what I want to say, open your favorite shell and enter the following code:

1 deffoo():

Press ENTER. As you can see, the shell does not print any output but waits for you to continue with the definition of the function. The shell will always be like this until you stop defining the function. This is because defining a function is a declaration. Well, it's a mixed statement that contains some other declarations, but it's still a statement. Until the function is called, the contents of this function will not be executed. The object that is actually executing a function type is created.

This leads us to focus on the 2nd. Again, the dynamic and interpretive nature of Python makes us believe that when the print bar line is executed, Python will first look for the variable called Bar in the local scope and then look for the global scope. But what actually happens is that the local scope is not completely dynamic. When the DEF statement executes, Python will statically retrieve the information from the local scope of the function. When it comes to bar=0 (not executing this line of code, but when the Python interpreter reads this line of code), it adds the ' bar ' variable to the local variable list of the Foo function. When the Foo function executes and Python prepares to execute the print bar line, it looks for the variable in the local scope, because the process is static, and Python knows that the variable has not been assigned a value, and the variable has no value, so it throws an exception.

You might ask: Why not throw this exception when declaring a function? Python knows beforehand that the bar variable is referenced before it is assigned to a value. The answer to this question is that Python has no way of knowing whether the local variable bar has been assigned a value. Take a look at the following example:

12345 bar =   42 def   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, but it doesn't know if the exception was quoted before the assignment until it really happened. Well, honestly, it doesn't even know if this variable is assigned!

12345678910111213 bar =42deffoo():    printbar    ifFalse:        bar =0>>> foo()Traceback (most recent call last):  File"<pyshell#17>", line 1, in<module>    foo()  File"<pyshell#16>", line 3, infoo    printbarUnboundLocalError: local variable ‘bar‘referenced before assignment

See the above code, although we as a smart creature can know very well not to assign value to bar. Python ignores that fact but still declares the local variable of bar.

I've said it long enough about this question. What we need is a solution, and I'll give you two solutions here.

12345678910 >>> bar =  42 def  foo (): ...     global  bar ...     print  bar ...     bar =  0 ... ... foo () 42 >>> bar 0

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, which is also more recommended, is not to use global variables. The Global keyword has never been used in many of my python development efforts. It's OK to know how to use it, but in the end try to avoid it. If you want to save the value from the beginning to the end of the code, define it as a property of a class. In this way, it is completely unnecessary to use global, when you want to use this value, through the properties of the class to access it:

1234567891011121314 >>> classBaz(object):...     bar =42... ... def foo():...     printBaz.bar  # global...     bar =0# local...     Baz.bar =8# global...     printbar... ... foo()... printBaz.bar4208

Novice Python often makes mistakes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.