10 errors that Python programmers often make (1)

Source: Internet
Author: User

About Python

Python is an explanatory, object-oriented, and advanced programming language with dynamic semantics. It has a built-in advanced data structure that combines the advantages of dynamic types and dynamic binding, making it attractive for Rapid Application Development, it can also be used as a script or glue language to connect to existing components or services. Python supports modules and packages to encourage modularization and code reuse.

About this article

The easy-to-learn syntax of Python may make Python developers-especially those Programming beginners-ignore some of its nuances and underestimate the capabilities of the language.

In view of this, this article lists Top 10 lists, enumerating errors that are sometimes hard to be captured by senior Python developers.

 

Common Errors #1: misuse expressions as default values of function parameters
 

Python allows default optional values for function parameters. Although this is a major feature of the language, it may lead to confusion in changing the default value. For example, let's take a look at the definition of this Python function:

 
 
  1. >>> def foo(bar=[]):        # bar is optional and defaults to [] if not specified  
  2. ...    bar.append("baz")    # but this line could be problematic, as we'll see...  
  3. ...    return bar  

A common error is that the optional parameter is set to the default value when the function does not provide the optional parameter for each call. In the code above, for example, people may want to repeatedly call foo () without explicitly specifying the bar parameter) and always return 'baz' because every time foo () the bar parameter is not set when calling.) the bar is set to [], which is an empty list ).

But let's take a look at what will happen in this case:

 
 
  1. >>> foo()  
  2. ["baz"]>>> foo()  
  3. ["baz", "baz"]>>> foo()  
  4. ["baz", "baz", "baz"] 

Yeah? Why do I append the default value "baz" to the existing list every time foo () is called instead of creating a new list?

The answer is that the default value of the function parameter is only evaluated once-when the function is defined. Therefore, when the bar parameter is initialized, its default value is an empty list), that is, when foo () is first defined, but when foo () is called, bar parameter is not specified) the parameter previously initialized by bar will continue to be used.

The following is a common solution:

 
 
  1. >>> def foo(bar=None):  
  2. ...    if bar is None:        # or if not bar:  
  3. ...        bar = []  
  4. ...    bar.append("baz")  
  5. ...    return bar  
  6. ...  
  7. >>> foo()  
  8. ["baz"]  
  9. >>> foo()  
  10. ["baz"]  
  11. >>> foo()  
  12. ["baz"]  
 
Common Errors #2: incorrect use of class variables
 

Consider the following example:

 
 
  1. >>> class A(object):  
  2. ...     x = 1 
  3. ...  
  4. >>> class B(A):  
  5. ...     pass 
  6. ...  
  7. >>> class C(A):  
  8. ...     pass 
  9. ...  
  10. >>> print A.x, B.x, C.x  
  11. 1 1 1 

For general use.

 
 
  1. >>> B.x = 2 
  2. >>> print A.x, B.x, C.x  
  3. 1 2 1 

Well, try again.

 
 
  1. >>> A.x = 3 
  2. >>> print A.x, B.x, C.x  
  3. 3 2 3 

What$ % #! &?? We only changed a.x. Why did C. x change?

In Python, class variables are processed as dictionaries internally, and follow the commonly referenced method to parse the order MRO ). Therefore, in the code above, because the x attribute in class C is not found, it will look up its base class. Although Python supports multiple inheritance, the above example only contains ). In other words, class C does not have its own x attribute, which is independent of class. Therefore, C. x is actually A reference of A. x.

Common Errors #3: specify an incorrect parameter for counter t

Suppose you have the following code:

 
 
  1. >>> try:  
  2. ...     l = ["a", "b"]  
  3. ...     int(l[2])  
  4. ... except ValueError, IndexError:  # To catch both exceptions, right?  
  5. ...     pass 
  6. ...  
  7. Traceback (most recent call last):  
  8.   File "<stdin>", line 3, in <module>  
  9. IndexError: list index out of range  

The problem here is that the distinct T statement does not accept the exception list specified in this way. On the contrary, in Python 2.x, using the syntax parse t Exception, e is to bind an Exception object to the secondOptionalIn this example, the parameter is e) for later use. Therefore, in the above example, the IndexError exception andNoYesCaptured by the except T statement. It is triggered when it is bound to a parameter named IndexError.

The correct way to capture multiple exceptions in a distinct T statement is to specify the first parameter as a tuple containing all exceptions to be caught. In addition, the as keyword should be used for code portability, because both Python 2 and Python 3 support this syntax:

 
 
  1. >>> try:  
  2. ...     l = ["a", "b"]  
  3. ...     int(l[2])  
  4. ... except (ValueError, IndexError) as e:    
  5. ...     pass 
  6. ...  
  7. >>>  
Common Errors #4: do not understand the Python Scope

Python performs resolution based on LEGB. LEGB isLOcal,ENclosing,GLobal,BThe abbreviation of uilt-in. It looks like "seeing Wen Zhiyi", right? In fact, there are some notes in Python. Let's take a look at the following code:

 
 
  1. >>> x = 10 
  2. >>> def foo():  
  3. ...     x += 1 
  4. ...     print x  
  5. ...  
  6. >>> foo()  
  7. Traceback (most recent call last):  
  8.   File "<stdin>", line 1, in <module>  
  9.   File "<stdin>", line 2, in foo  
  10. UnboundLocalError: local variable 'x' referenced before assignment  

What's wrong here?

The above problem occurs because when you assign a value to a variable in the scope, Python will automatically treat it as a local variable in the current scope, which will hide the variable with the same name in the external scope.

Many people are surprised that they get an UnboundLocalError when they add a value assignment statement somewhere in the function body of the code that can run normally before. (You can learn more here)

This problem is more common when developers use lists. See the following example:

 
 
  1. >>> Lst = [1, 2, 3]
  2. >>> Def foo1 ():
  3. ... Lst. append (5) # No problem...
  4. ...
  5. >>> Foo1 ()
  6. >>> Lst
  7. [1, 2, 3, 5]
  8.  
  9. >>> Lst = [1, 2, 3]
  10. >>> Def foo2 ():
  11. ... Lst + = [5] #... but there is a problem here!
  12. ...
  13. >>> Foo2 ()
  14. Traceback (most recent call last ):
  15. File "<stdin>", line 1, in <module>
  16. File "<stdin>", line 2, in foo
  17. UnboundLocalError: local variable 'lst' referenced before assignment

Hmm? Why does foo2 report an error while foo1 does not?

The reason is the same as in the previous example, but it is more elusive. Foo1 does not assign values to the lst, but foo2 does. You know, lst + = [5] is the abbreviation of lst = lst + [5]. We tryAssignmentPython is used as a local variable ). In addition, the value assignment operation for lst is based on the lst itself, which is once again treated as a local variable by Python), but it is not defined yet. Therefore, an error occurred!

Common Errors #5: modifying a List during iteration)

The problem in the following code should be quite obvious:

 
 
  1. >>> odd = lambda x : bool(x % 2)  
  2. >>> numbers = [n for n in range(10)]  
  3. >>> for i in range(len(numbers)):  
  4. ...     if odd(numbers[i]):  
  5. ...         del numbers[i]  # BAD: Deleting item from a list while iterating over it  
  6. ...  
  7. Traceback (most recent call last):  
  8.         File "<stdin>", line 2, in <module>  
  9. IndexError: list index out of range  

Removing elements from a List or array during iteration is a well-known error for any experienced developer. Although the above example is very obvious, many advanced developers do not mean it in more complex code.

Fortunately, Python contains a large number of simple and elegant programming examples that can greatly simplify and refine code if used properly. The advantage is that the code can be simplified and streamlined, and the code can be better avoided in the program.Modify a list during IterationList)Such a bug. An example is the recursive list comprehensions ). In addition, the recursive list comprehensions is particularly useful for this problem. By changing the implementation above, we can get an excellent code:

 
 
  1. >>> odd = lambda x : bool(x % 2)  
  2. >>> numbers = [n for n in range(10)]  
  3. >>> numbers[:] = [n for n in numbers if not odd(n)]  # ahh, the beauty of it all  
  4. >>> numbers  
  5. [0, 2, 4, 6, 8]  
Common Errors #6: Do not understand how Python binds variables in closures
 

Let's look at the example below:

 
 
  1. >>> def create_multipliers():  
  2. ...     return [lambda x : i * x for i in range(5)]  
  3. >>> for multiplier in create_multipliers():  
  4. ...     print multiplier(2)  
  5. ...  

You may want to obtain the following output results:

 
 

But the actual result is:

 
 
  1. 8  
  2. 8  
  3. 8  
  4. 8  
  5. 8  

Surprised!

This occurs because the variable used in the closure is assigned a value only when the function is called. Therefore, in the code above, when the returned function is called, Python will search for the corresponding I value in the scope of the function when it is called, and the loop has ended, so I is assigned the final value -- 4 ).

The solution is hack:

 
 
  1. >>> def create_multipliers():  
  2. ...     return [lambda x, i=i : i * x for i in range(5)]  
  3. ...  
  4. >>> for multiplier in create_multipliers():  
  5. ...     print multiplier(2)  
  6. ...  

Here, we use the default parameter to generate an anonymous function to achieve the desired result. Some people say this method is clever, some say it is hard to understand, and others hate it. However, if you are a Python developer, it is important to understand this behavior.


Related Article

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.