Python traps and points of attention often encountered in development

Source: Internet
Author: User
The recent use of Python has encountered a number of pits, such as the Datetime.datetime.now () variable object as the default parameter of the function, the module cycle dependency and so on.

Record here, convenient for later inquiries and additions.

Avoid mutable objects as default parameters

In the process of using functions, the default parameters are often involved. In Python, when you use a Mutable object as the default parameter, you can produce unintended results.

Let's look at an example:

Def append_item (a = 1, b = []):    b.append (a)    print B     append_item (a=1) Append_item (a=3) Append_item (a=5)

The result is:

[1] [1, 3] [1, 3, 5]

As you can see from the results, the function parameter B is not initialized to [] when the Append_item function is called, but it retains the value of the previous function call, two times later.

This result is obtained because in Python, the default value of a function parameter is initialized only once when the function is defined.

Here's an example of what this feature of Python looks for:

Class Test (object):      def __init__ (self):          print ("init Test")             def arg_init (A, B = Test ()):      print (a)  Arg_init (1)  Arg_init (3)  Arg_init (5)

The result is:

Init Test135

As you can see from the results of this example, the test class is only instantiated once, which means that the default parameter is independent of the number of function calls, and is initialized only once when the function is defined.

Correct use of variable default parameters

For variable default parameters, we can use the following pattern to avoid unintended results above:

Def append_item (a = 1, B = none):    if B is none:        b = []    b.append (a)    print B     append_item (a=1) append_it EM (a=3) Append_item (a=5)

The result is:

[1] [3] [5]

Scopes in Python

Python's scope parsing order is local, enclosing, Global, built-in, which means that the Python interpreter parses the variable in this order.


See a simple example:

Global_var = 0def Outer_func ():    Outer_var = 1         def inner_func ():        Inner_var = 2                 print "Global_var is:", Glo Bal_var        print "Outer_var is:", Outer_var        print "Inner_var is:", Inner_var             inner_func ()     Outer_func ()


The result is:

Global_var Is:0outer_var Is:1inner_var Is:2

In Python, one thing to note about scopes is that when assigning values to a variable within a scope, Python considers the variable to be a local variable of the current scope.


It is also relatively easy to understand that the NUM variable is assigned to the following code var_func, so num here is the local variable for the var_func scope.

num = 0def var_func ():    num = 1    print "num is:", num     var_func ()

Question One

However, when we use the variable in the following way, it creates a problem:

num = 0def var_func ():    print "num is:", num    num = 1     var_func ()

The results are as follows:

unboundlocalerror:local variable ' num ' referenced before assignment

The mistake was made because we assigned the NUM variable in Var_func, so the Python interpreter would assume that NUM is a local variable for the Var_func scope, but when the code executes to the print "num is:", the NUM statement, Num is still undefined.


Question Two

The above error is still more obvious, there is a more subtle form of error as follows:

Li = [1, 2, 3]def foo ():    li.append (4)    print Lifoo () def bar ():    li +=[5]    print Libar ()

The result of the code is:

[1, 2, 3, 4] unboundlocalerror:local variable ' li ' referenced before assignment

In the Foo function, the global Li variable is used in the order of the Python's scope parsing, but in the bar function, the LI variable is assigned, so Li is treated as a variable in the bar scope.


For this problem with the bar function, you can pass the Global keyword.

Li = [1, 2, 3]def foo ():    li.append (4)    print Li     foo () def Bar ():    global Li    li +=[5]    print Li     Bar ()

Class Property hiding

In Python, there are class properties and instance properties. The Class property belongs to the class itself and is shared by all instances of the class.

Class properties can be accessed and modified through the class name, or accessed and modified through class instances. However, when an instance defines a property with the same name as the class, the Class property is hidden.


Look at the following example:

Class Student (object):    books = ["Python", "JavaScript", "CSS"]    def __init__ (self, Name, age):        self.name = Name        Self.age = Age    pass     wilber = Student ("Wilber", +) print "%s is%d years old"% (Wilber.name, wilber.age) pr int Student.booksprint wilber.bookswilber.books = ["HTML", "AngularJS"]print student.booksprint Wilber.booksdel Wilber.booksprint Student.booksprint Wilber.books

The result of the code is that at first the Wilber instance can access the class's books property directly, but after the instance Wilber defines an instance property named Books, the Wilber property of the books instance "hides" the books property of the class When the books property of the Wilber instance is removed, wilber.books then corresponds to the books attribute of the class.

Wilber is years old[' python ', ' javascript ', ' css ' [' Python ', ' javascript ', ' css ' [' Python ', ' javascript ', ' CSS '] [' HTML ', ' AngularJS ' [' Python ', ' javascript ', ' css ' [' Python ', ' javascript ', ' CSS ']

When using inheritance in Python values, you should also be aware of the hidden properties of the class. For a class, you can view all of the class properties through the __dict__ property of the class.


When a class property is accessed through the class name, the __dict__ property of the class is first looked up, and if the class attribute is not found, the parent class will continue to be looked up. However, if a subclass defines a class property that has the same name as the parent class, the class property of the child class hides the class property of the parent class.


See an example:

Class A (object):    count = 1     class B (a):    Pass         class C (a):    pass             print A.count, B.count, C.count      B.count = 2print a.count, b.count, C.count      A.count = 3print A.count, b.count, c.count     print B.__dict__print c.__dict__

As a result, when Class B defines the class attribute of count, the Count property of the parent class is hidden:

1 1 2 2 3{' Count ': 2, ' __module__ ': ' __main__ ', ' __doc__ ': none}{' __module__ ': ' __main__ ', ' __doc__ ': None}

A tuple is "mutable."

In Python, a tuple is an immutable object, but the immutable reference here is that the total element of the container is immutable (that is, the ID of the element), but the value of the element can be changed.

TPL = (1, 2, 3, [4, 5, 6]) Print ID (TPL) Print ID (tpl[3]) tpl[3].extend ([7, 8]) print Tplprint ID (TPL) Print ID (tpl[3])

The code results are as follows, and for the TPL object, each of its elements is immutable, but Tpl[3] is a list object. That is, the ID (tpl[3]) is immutable for this TPL object, but Tpl[3] is indeed mutable.

3676457638639896 (1, 2, 3, [4, 5, 6, 7, 8]) 3676457638639896

Python's shades of Copy

In the operation of assigning a value to a Python object, it is important to pay attention to the object's dark-and-dark copy, which can be accidentally trampled.


The effect of a shallow copy occurs when the following operation is used:


Using the slice [:] Action

Using factory functions (such as List/dir/set)

Using the copy () function in the Copy module

Copy () using the shallow copy function inside the Copy module:

Import Copywill = ["would", "["], ["Python", "C #", "JavaScript"]]wilber = Copy.copy (would) print ID (would) print Willprint [ID (el e) for ele in Will]print ID (Wilber) print Wilberprint [ID (ele) for ele in wilber]will[0] = "Wilber" Will[2].append ("CSS") pri NT ID (would) print Willprint [ID (ele) for ele in Will]print ID (Wilber) print Wilberprint [ID (ele) for ele in Wilber]

Use the deep copy function inside the Copy module deepcopy ():

Import Copywill = ["would", "["], ["Python", "C #", "JavaScript"]]wilber = Copy.deepcopy (would) print ID (would) print willprint [i D (ele) for ele in Will]print ID (Wilber) print Wilberprint [ID (ele) for ele in wilber]will[0] = "Wilber" Will[2].append ("CSS" ) Print ID (would) print Willprint [ID (ele) for ele in Will]print ID (Wilber) print Wilberprint [ID (ele) for ele in Wilber]

Module Cycle dependent

When importing a module using import in Python, sometimes it generates a module loop dependency, such as the following example, where the module_x module and the Module_y module are interdependent and generate errors when running module_y.py.

# module_x.pyimport module_y     def inc_count ():    module_y.count + = 1    print module_y.count          # Module_ Y.pyimport Module_xcount = 10def run ():    module_x.inc_count ()     run ()


In fact, in the process of coding should avoid the situation of cyclic dependence, or code refactoring process to eliminate the cyclic dependency.


Of course, the above problems can be solved, the common solution is to clear the reference relationship, so that a module in the real need to import (usually put into the function inside).


For the above example, you can change the module_x.py to the following form and import the module_y inside the function:

# Module_x.pydef Inc_count ():    import module_y    Module_y.count + = 1
  • 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.