The 10 most common mistakes that Python developers make

Source: Internet
Author: User


Summary: Python is a simple and easy-to-learn programming language with simple and clear syntax and a rich and powerful class library. In the daily development, developers are very tolerant of some low-level errors, this article summarizes the developers most likely to make 10 mistakes.

Python is a simple and easy-to-learn programming language with simple and clear syntax and a rich and powerful class library. Unlike most other programming languages that use curly braces, it uses indentation to define the block of statements.

In the usual work, Python developers can easily make a few small mistakes, these errors are easy to avoid, this article summarizes the Python developers most commonly committed 10 errors, together to see, I do not know that you have been shot.

1. Abusing expressions as default values for function parameters

Python allows developers to specify a default value for a function parameter, although this is a feature of the language, but when the argument is variable, it can easily lead to confusion, for example, the following function definition:

>>> def foo (bar=[]):        # Bar is optional and defaults to [] if not specified ...    Bar.append ("Baz")    # But this line could is problematic, as we'll see ...    Return bar

In the above code, once the Foo () function is called repeatedly (without specifying a bar parameter), it will always return ' bar ' because no parameters are specified, and foo () is given [] each time it is called. Here's a look at the result of doing this:

>>> foo () ["Baz"]>>> foo () ["Baz", "Baz"]>>> foo () ["Baz", "Baz", "Baz"]

Solution:

>>> def foo (bar=none): ...    If bar is none:# or if not bar: ...        bar = [] ...    Bar.append ("baz")    ... Return bar...>>> foo () ["Baz"]>>> foo () ["Baz"]>>> foo () ["Baz"]

2. Using class variables incorrectly

Let's look at the following example:

>>> class A (object): ...     x = 1...>>> class B (A): ...     Pass...>>> class C (A): ...     pass...>>> print a.x, b.x, c.x1 1 1

It makes sense to:

>>> b.x = 2>>> print a.x, b.x, c.x1 2 1

Let's do it again:

>>> a.x = 3>>> print a.x, b.x, c.x3 2 3

Just changed the a.x, why c.x also changed.

In Python, class variables are internally processed as dictionaries and follow the method resolution order (MRO). In the above code, because attribute x is not found in Class C, it looks for its base class (only a in the example above, although Python supports multiple inheritance). In other words, C itself has no x attribute, independent of a, so referencing c.x is actually referring to a.x.

3. Specify an incorrect parameter for the exception

Suppose the code has the following code:

>>> Try:     ... L = ["A", "B"] ...     Int (l[2]) ... except ValueError, Indexerror: # to  catch both exceptions, right?...     Pass ... Traceback (most recent):  File "", line 3, inindexerror:list index out of range

The problem here is that the except statement does not need this way to specify the exception list. However, in Python 2.x, except exception,e is usually used to bind the second parameter in the exception so that it can be checked further. Therefore, in the above code, the Indexerror exception is not captured by the except statement, and the exception is finally bound to a parameter named Indexerror.

The correct way to catch multiple exceptions in an exception statement is to specify the first parameter as a tuple that contains all the caught exceptions. At the same time, using the AS keyword to ensure maximum portability, both Python 2 and Python 3 support this syntax.

>>> Try:     ... L = ["A", "B"] ...     Int (l[2]) ... except (ValueError, Indexerror) as E: ...     Pass...>>>

4. Misunderstanding Python rule scope

The scope resolution of Python is based on the LEGB rules, which are local, enclosing, Global, built-in, respectively. In fact, this parsing method also has some mystery, see the following example:

>>> x = 10>>> def foo (): ...     x + = 1     ... Print x...>>> foo () Traceback (most recent call last):  File "", Line 1, inFile "", Line 2, in Foounboundlocale rror:local variable ' x ' referenced before assignment

Many people will be amazed when they add a parameter statement to the function body of the work, and report a unboundlocalerror error in the previously working code (click here for a more detailed description).

It is easy for developers to make this mistake when using the list, take a look at the following example:

>>> LST = [1, 2, 3]>>> def foo1 ():     ... Lst.append (5)   # This Works ok......>>> foo1 () >>> lst[1, 2, 3, 5]>>> lst = [1, 2, 3]>> > Def foo2 ():     ... LST + = [5]      # bombs!... >>> Foo2 () Traceback (most recent call last):  File "", Line 1, inFile " ", line 2, in foounboundlocalerror:local variable ' LST ' referenced before assignment

Why did Foo2 fail and foo1 run normally?

The answer is the same as the previous example, but there are some subtleties. The foo1 is not assigned to LST, and Foo2 is assigned to the value. LST + = [5] is actually LST = LST + [5], attempting to assign a value to LST (so suppose Python is in a local scope). However, we are looking for the value specified for LST to be based on the LST itself, in fact not yet determined.

5. Modify the Traversal list

The following code is obviously wrong:

>>> odd = lambda x:bool (x% 2) >>> numbers = [n for n in range]]>>> for I in range (Len (numb ers)): ...     If Odd (Numbers[i]): ...         Del Numbers[i]  # bad:deleting item from a list while iterating over it ... Traceback (most recent):    File "", line 2, inindexerror:list index out of range

It is a low-level error to delete a list while traversing. People with a little bit of experience will not commit.

Modify the above code to execute correctly:

>>> odd = lambda x:bool (x% 2) >>> numbers = [n for n in range (Ten)]>>> numbers[:] = [n for n i N numbers if not odd (n)]  # Ahh, the beauty of it all>>> numbers[0, 2, 4, 6, 8]

6. How to bind variables in closures

Look at the following example:

>>> def create_multipliers ():     ... return [Lambda x:i * x for I in range (5)]>>> for multiplier in Create_multipliers (): ...     Print multiplier (2) ...

The result you expect is:

02468

As a matter of fact:

88888

is not very surprised! This occurs primarily because of the late-bound behavior of Python, which is used in closures while the intrinsic function calls it.

Solution:

>>> def create_multipliers ():     ... return [lambda x, i=i:i * x for I in range (5)]...>>> for multiplier in Create_multipliers (): ...     Print multiplier (2) ... 02468

7. Create a loop module dependency relationship

Suppose there are two files, a.py and b.py, and then each imported, as follows:

In the a.py:

Import Bdef F ():    return b.xprint F ()

In the b.py:

Import ax = 1def g ():    print A.F ()

First, let's try importing a.py:

>>> Import A1

Can work well, perhaps you will be surprised. After all, we did have a circular import here, shouldn't there be a problem?

The mere existence of a circular import is not a problem with Python itself, and if a module is imported, Python will not attempt to re-import it. According to this, each module may encounter some problems at run time when attempting to access a function or variable.

What happens when we try to import b.py (no previous import of a.py):

>>> Import Btraceback (most recent): File "    ", line 1, in  file "b.py", line 1, inimport a    Fi Le "a.py", line 6, Inprint F ()    File "a.py", line 4, in Freturn b.xattributeerror: ' Module ' object have no attribute ' x '

The problem here is that when importing b.py, you try to import a.py, which calls F () and tries to access b.x. But b.x is not defined.

You can fix this by simply modifying the G () function that b.py imports into a.py:

x = 1def g (): Import a# This would be evaluated if only if    g () is called    print A.F ()

Whenever you import, everything works:

>>> import b>>> B.G () # Printed a first time since module ' a ' calls ' Print f () ' At the end1# printed a s Econd time, this one was our call to ' G '

8. Conflict with Python standard library module name

Python has a very rich library of modules and supports "out of the box". Therefore, a naming conflict event can occur easily if you do not deliberately avoid it. For example, there may be a email.py module in your code that, because of its name, is likely to conflict with the standard library module that Python comes with.

9. The difference between python2.x and python3.x is not dealt with as stipulated

Take a look at foo.py:

Import Sysdef Bar (i):    if i = = 1:        raise Keyerror (1)    if i = = 2:        raise ValueError (2) def bad ():    e = none
    try:        Bar (int (sys.argv[1)))    except Keyerror as E:        print (' key error ')    except ValueError as E:        Print (' value error ')    print (e) bad ()

In Python 2 it works well:

$ python foo.py 1key error1$ python foo.py 2value Error2

But in Python 3:

$ python3 foo.py 1key Errortraceback (most recent call last):  file "foo.py", Line, Inbad ()  file "foo.py", Lin E, in Bad    print (e) unboundlocalerror:local variable ' e ' referenced before assignment

Solution:

Import Sysdef Bar (i):    if i = = 1:        raise Keyerror (1)    if i = = 2:        raise ValueError (2) def good ():    exceptio n = None    try:        bar (int (sys.argv[1]))    except Keyerror as e:        exception = e        print (' key error ')    Except ValueError as e:        exception = e        print (' value error ')    print (Exception) good ()

To run the results in py3k:

$ python3 foo.py 1key error1$ python3 foo.py 2value Error2

There are a lot of considerations and discussions about Python 2 and Python 3 when porting code in the Python recruiting guide, so you can go and see.

10. Misuse of the __del__ method

For example, here is a file called mod.py:

Import Fooclass Bar (object):       ...    def __del__ (self):        foo.cleanup (Self.myhandle)

Below, you perform the following actions in the another_mod.py file:

Import Modmybar = mod. Bar ()

You will get a Attributeerror exception.

For the reasons why this exception occurs, click here for details. When the interpreter is closed, the module's global variables are all set to none. So, in the example above, when __del__ is called, Foo is all set to none.

A good solution is to use Atexit.register () instead. By the way, when the program finishes, your registered handler stops working before the interpreter shuts down.

The code to fix the above problem:

Import fooimport atexitdef Cleanup (handle):    foo.cleanup (Handle) class Bar (object):    def __init__ (self):        ...        Atexit.register (cleanup, self.myhandle)

With the normal termination of the program, this implementation provides a neat and reliable way to invoke any functionality that needs to be cleaned.

Summarize

Python is a powerful and flexible programming language with many mechanisms and patterns to greatly improve productivity. As with any language or software tool, people have a restrictive understanding or appreciation of their abilities, some of them do more harm than better, and sometimes they lead to some pitfalls. Learn the nuances of a language, understand some common pitfalls, and help you get farther on the road for developers.

Original: http://sanliangzhi.com/hot/4063.html

Classic: Http://sanliangzhi.com/Ittext/Index/tag_list/ftag/python.html

The 10 most common mistakes that Python developers make

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.