Python advanced-function default parameters (detailed description), python advanced

Source: Internet
Author: User

Python advanced-function default parameters (detailed description), python advanced

1. Default Parameters

To simplify function calling, python provides the default parameter mechanism:

def pow(x, n = 2):  r = 1  while n > 0:    r *= x    n -= 1  return r

In this way, when the pow function is called, The last parameter can be omitted without being written:

print(pow(5)) # output: 25

When defining a function with default parameters, note the following:

The required parameter must be in front, and the default parameter is in the back;

Which parameter is set as the default parameter? Generally, if the parameter value changes little, it is set to the default parameter.

Python standard library practices

Python built-in functions:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

The function signature shows that printing statements that use simple calls such as print ('Hello python') actually pass in many default values. The default parameters make function calls very simple.

2. default parameters with errors

Reference an official classic example address:

def bad_append(new_item, a_list=[]):  a_list.append(new_item)  return a_listprint(bad_append('1'))print(bad_append('2'))

This example is not printed as expected:

['1']['2']

But printed:

['1']['1', '2']

In fact, this error is not caused by the default parameter, but is caused by incorrect understanding of the initialization of the default parameter.

3. default parameter initialization

Actually,The default parameter value is calculated only once during definition.So every time you call a function using the default parameter, the default parameter values are the same.

Here is an intuitive example:

Import datetime as dtfrom time import sleepdef log_time (msg, time = dt. datetime. now (): sleep (1) # print ("% s: % s" % (time. isoformat (), msg) log_time ('msg 1') log_time ('msg 2') log_time ('msg 3 ')

Run this program and the output is:

2017-05-17T12:23:46.327258: msg 12017-05-17T12:23:46.327258: msg 22017-05-17T12:23:46.327258: msg 3

Even if sleep (1) is used to suspend the thread for one second, the program execution is quickly ruled out. The output time of the three calls is the same, that is, the default time value of the three calls is the same.

The above example may not completely explain the problem. The following describes the problem by observing the memory address of the default parameter.

First, you need to understand the built-in function id (object ):

Id (object)
Return the "identity" of an object. this is an integer which is guaranteed to be unique and constant for this object during its lifetime. two objects with non-overlapping lifetimes may have the same id () value.

CPython implementation detail:This is the address of the object in memory.

That is, the id (object) function returns the unique identifier of an object. This identifier is an integer that is unique and unchanged during the lifecycle of an object. In an overlapping lifecycle, two objects may have the same id value.
In CPython interpreter implementation, the value of id (object) is the memory address of the object.

The following example uses the id (object) function to clearly illustrate the problem:

def bad_append(new_item, a_list=[]):    print('address of a_list:', id(a_list))  a_list.append(new_item)  return a_listprint(bad_append('1'))print(bad_append('2'))

Output:

address of a_list: 31128072['1']address of a_list: 31128072['1', '2']

Call bad_append twice. The default parameter a_list has the same address.

In addition, a_list is a variable object. Using the append method to add new elements does not cause the list object to be re-created and the address to be re-allocated. In this way, the object is modified at the address indicated by the default parameter. The last modification is displayed when the address is used again in the next call.

Then, it is not surprising that the above outputs are directed to the same memory address.

Iv. Variable and immutable default parameters

When the default parameter points to a mutable object and an object of an unchangeable type, the behavior is different.

The variable default parameters are the same as the appeal example.

Unchangeable default parameters

First, let's look at an example:

def immutable_test(i = 1):  print('before operation, address of i', id(i))  i += 1  print('after operation, address of i', id(i))  return i  print(immutable_test())print(immutable_test())

Output:

before operation, address of i 1470514832after operation, address of i 14705148482before operation, address of i 1470514832after operation, address of i 14705148482

Obviously, the default parameter I value for the second call will not be affected by the first call. Because I points to an immutable object, operations on I will cause memory re-allocation and re-creation of the object, then the name I points to another address after I + = 1 in the function; according to the rules of the default parameter, the address that I points to is also the address that the function is assigned during the next call. The value of 1 is not changed.

In fact, variable default parameters and immutable default parameters are discussed here, which does not have much value. Just like the so-called value transfer or reference transfer in other languages, it will not only affect the default parameters.

5. Best practices

The multiple calls of an unchangeable default parameter do not have any impact. The results of multiple calls of a variable default parameter do not meet expectations. When you use a variable default parameter, You Cannot initialize the parameter only once during function definition. Instead, you must initialize the parameter at each call.

The best practice is to specify the value of the variable default parameter as None when defining a function, and rebind the value of the default parameter within the function body. The following is an application of the best practices for the above two examples of variable default parameters:

def good_append(new_item, a_list = None):  if a_list is None:    a_list = []  a_list.append(new_item)  return a_listprint(good_append('1'))print(good_append('2'))print(good_append('c', ['a', 'b']))
import datetime as dtfrom time import sleepdef log_time(msg, time = None):  if time is None:    time = dt.datetime.now()  sleep(1)  print("%s: %s" % (time.isoformat(), msg))log_time('msg 1')log_time('msg 2')log_time('msg 3')

The above Python advanced-default function parameters (detailed description) are all the content shared by the editor. I hope to give you a reference and support for the help house.

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.