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