Python when list,dic as the default parameter of the pit of the father's place

Source: Internet
Author: User

Look at the code first:

def foo (A, b =[]):    b.append (a)    print Bfoo (1) foo (2)

As a result, imagine:

>>>

[1]

[2]

>>>

is actually:

>>>

[1]

[1, 2]

>>>


View official documents: Https://docs.python.org/2.7/tutorial/controlflow.html#default-argument-values

The default values is evaluated at the point's function definition in the defining scope.

The default value is evaluated only once.

This makes a difference when the default was a mutable object such as a list, dictionary, or instances of most classes.



Under the general translation:

The default parameter is assigned only when the DEF statement is executed, and it is assigned one value at a time. If you encounter a mutable type of list or DIC, there may be some unexpected differences.


On a question: http://www.zhihu.com/question/21924859 mentions that when Python executes def, a new function is created based on the compiled bytecode and namespace, and the value of the default parameter is computed. The default parameter is a property of the new function (yes, the function is also an object), see below:

>>> def foo (bar=[]): ...     return bar>>> foo.func_name ' foo ' >>> foo.func_defaults ([],)


In the Trap! Python parameter default value article mentions a piece of code:

Def a ():    print ' A executed '    return []def B (X=a ()):    print ' ID (x): ', ID (x)    x.append (5)    print ' x: ', Xfor I in range (2):    print ' * ' *20    B ()    print ' b.__defaults__: ', b.__defaults__    print ' ID (b.__defaults__ [0]): ', ID (b.__defaults__[0]) for I in Range (2):    print ' * ' *20    B (List ())    print ' b.__defaults__: ', b.__ defaults__    print ' ID (b.__defaults__[0]): ', ID (b.__defaults__[0])    
Results:


Under Analysis:

It is seen from "a executed" that the default value of the parameter is calculated before the DEF is executed.

A total of four calls to B (), the first two no arguments, with the default parameters. The following result shows that X does use the default parameters:

ID (x): 48161096

ID (b.__defaults__[0]): 48161096

The third time B (), the argument list (), so x is its own ID, do not need to use the default parameters:

ID (x): 48033160

ID (b.__defaults__[0]): 48161096

Fourth time B (), parameter list (), x is a new ID, no default parameters are required:

ID (x): 48032776

ID (b.__defaults__[0]): 48161096

Summary below:

The default parameters for Python are in the b.__defaults__ list, which is called when the default parameters are needed, and it's a quiet place to stay, a person. (Suddenly the wind changed?) )



Back to the original code of the topic:

def foo (A, b =[]):    b.append (a)    print Bfoo (1) foo (2)

Because there is no incoming parameter, so the default parameter, the default B is a list ah, so the more append more.


Changes in the official documentation:

def foo (A, B=none):    if B is None:        b = []    b.append (a)    print Bfoo (1) foo (2)


========================= added to 20150808===========================

See a piece of code, in Def in class, is the ID of the default parameter the same?

If I had many instances of class obj, would each obj have a different ID? The ID of the default parameter for the function in obj should be different.

Class Demo_list:    def __init__ (self, l=[]):        SELF.L = l        print ' ID (SELF.L): ', id (SELF.L)            def add (self, ele ):        Self.l.append (ele) def appender (ele):    obj = demo_list ()    print ' id (obj): ', id (obj)    obj.add (ele)    print Obj.lif __name__ = = "__main__": for    I in range (5):        Appender (i)
The result is:

ID (SELF.L): 49415560id (obj): 49357000[0]id (SELF.L): 49415560id (obj): 49277192[0, 1]id (SELF.L): 49415560id (obj): 49277192[0, 1, 2]id (SELF.L): 49415560id (obj): 49277192[0, 1, 2, 3]id (SELF.L): 49415560id (obj): 49277192[0, 1, 2, 3, 4]

In addition to the first obj, each obj points to the same ID.

The default parameter for each obj is to point to the same ID, well, the default parameter, L, is the same object.

Let's put the focus on the default parameter, what if I specify a parameter?

Change obj = Demo_list () to: obj = demo_list (list ())

The result is:

ID (SELF.L): 48242888id (obj): 48243400[0]id (SELF.L): 48163080id (obj): 48243400[1]id (SELF.L): 48243400id (obj): 48246024[2]id (SELF.L): 48246024id (obj): 48244296[3]id (SELF.L): 48244296id (obj): 48249800[4]
You can see that each L is a different object, and it doesn't use the default parameters, well, that's right.

Then the ID (obj) is also roughly different. "There's a pit here, to be verified."

With respect to the ID problem of obj, I guess it is the Python optimization problem, which is pre-allocated for small things like int ( -5~256), so both i=10 and j=10 are optimized to point to the same ID object. So I'm daring to guess that when an object is small , Python is also an object that points to the same ID for something similar. The first section of the code is pointing to the same list, the similarity is high, the same obj ID is more, the second code because each list ID is different, the similarity is low, obj some ID is the same, some are not the same.

Based on my guess, I did an experiment that made the class demo_list a little bit more complicated, and a little bit bigger, Python wouldn't be easy to optimize.

Class Demo_list:    def __init__ (self, l=[]):        SELF.L = l        print ' ID (SELF.L): ', id (SELF.L)            def add (self, ele ):        Self.l.append (Ele) def a (self): pass def b (self): pass    def c (self):        pass    def appender (ele):    obj = demo_list (list ())    print ' id (obj): ', id (obj)    obj.add (ele)    Print Obj.lif _ _name__ = = "__main__": for    I in range (5):        Appender (i)
Results:

ID (SELF.L): 48899656id (obj): 48898248[0]id (SELF.L): 48818440id (obj): 48819592[1]id (SELF.L): 48819592id (obj): 48901256[2]id (SELF.L): 48901256id (obj): 48901384[3]id (SELF.L): 48901384id (obj): 48898248[4]

As it turns out, there are three more functions a (), B (), C (), and each obj has a different ID.
Hey, this optimization, and don't know how to say it well. In fact, in theory, every obj should have been different from the one that ID said.


Well, the default value of this parameter can not be used as a static variable (although the Py has not heard support for static variables said) to use it?

Parameter default values are only executed once = = Static variables are initialized only once.

It seems to be true.

wow~ so cool~








Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Python when list,dic as the default parameter of the pit of the father's place

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.