Describes the default parameters in Python functions in detail.

Source: Internet
Author: User

Describes the default parameters in Python functions in detail.

import datetime as dt def log_time(message, time=None):  if time is None:    time=dt.datetime.now()  print("{0}: {1}".format(time.isoformat(), message))

Recently, I found a very disgusting bug in a piece of Python code due to incorrect use of default parameters. If you already know all the content about the default parameters, just want to laugh at me, Please jump directly to the end of this article. Ah, I wrote this code, but I am very sure that I was possessed by the devil that day. You know, sometimes this is the case.

This article only summarizes some basic content about the standard parameters and default parameters of Python functions. Remind you to pay attention to the possible traps in your code. If you are new to Python and want to write some Functions, I really recommend you read the Functions in the Python official manual. The links are as follows: Defining Functions and More on Defining Functions.
A simple review of functions

Python is a powerful object-oriented language that has pushed this programming paradigm to its peak. However, object-oriented programming still needs to rely on the function concept, and you can use it to process data. Python has a broader concept for callable objects, that is, any object can be called, which means to apply data to it.

A function is a callable object in Python. At first glance, it acts like a function in other languages. They get some data, which is called parameters, process them, and then return the result (if there is no return statement, it is None)

The parameter is declared as a placeholder (when defining a function) to represent objects actually passed in when the function is called. In Python, you do not need to declare the parameter type (for example, as you did in C or Java) because the Python philosophy relies on polymorphism.

Remember, Python variables are references, that is, the memory address of the actual variables. This means that Python functions always work in the "Address Transfer" mode (a C/C ++ term is used here). When you call a function, instead of copying a parameter value to replace the placeholder, The placeholder points to the variable itself. This leads to a very important result: You can change the value of this variable within the function. Here is a good visual explanation about the reference mechanism.

References play a very important role in Python, which is the backbone of the Full-state Python mode. For more information about this important topic, click this link.

To check whether you understand this basic feature of the language, follow this simple code (the variable ph represents a "placeholder (placeholder )")
 

>>> def print_id(ph):... print(hex(id(ph)))...>>> a = 5>>> print(hex(id(a)))0x84ab460>>> print_id(a)0x84ab460>>>>>> def alter_value(ph):... ph = ph + 1... return ph...>>> b = alter_value(a)>>> b6>>> a5>>> hex(id(a))'0x84ab460'>>> hex(id(b))'0x84ab470'>>>>>> def alter_value(ph):... ph.append(1)... return ph...>>> a = [1,2,3]>>> b = alter_value(a)>>> a[1, 2, 3, 1]>>> b[1, 2, 3, 1]>>> hex(id(a))'0xb701f72c'>>> hex(id(b))'0xb701f72c'>>>

If you are not surprised by what happened here, it means that you have mastered one of the most important parts of Python. you can skip the following explanation with confidence.

The print_id () function shows that the placeholders inside the function are exactly the same as the variables passed in when running (their memory addresses are the same ).

The alter_value () of the two versions is intended to change the value of the input parameter. As you can see, the first alter_value () does not change the value of variable a as the second alter_value. Why? In fact, they both act the same way. They all try to modify the value of the input original variable. However, in Python, some variables are immutable, and integers are listed here. On the other hand, the list is not immutable, so the function can complete the work guaranteed by its name. Here, you can find a more detailed introduction to immutable types.

There are some things to be said about functions in Python, but these are basic knowledge about standard parameters.
Default parameter value

Sometimes you need to define a function to accept a parameter, and the function has different behaviors when the parameter appears or does not appear. If a language does not support this situation, you only have two options: the first is to define two different functions and decide which function to call each time, the second method is both feasible, but not optimal.

Like other languages, Python supports default parameter values, that is, function parameters can be specified during call or left blank to automatically accept a predefined value.

An example of a very simple (and useless) default value is as follows:
 

def log(message=None):  if message:    print("LOG: {0}".format(message))

This function can be run with a parameter (it can be None)

 >>> log("File closed")LOG: File closed>>> log(None)>>>

But it can also run without parameters. In this case, it accepts the default value set in a function prototype (None in this example)
 

>>> log()>>>

You can find more interesting examples in the standard library, such as in the open () function (please refer to the official documentation)
 

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

The function prototype can be proved. For example, a call like f = open ('/etc/hosts') hides many parameters (such as mode, buffering, encoding, etc.) by passing in the default value ), and makes the typical application cases of this function very easy to use.

As you can see in the built-in open () function, we can use standard or default parameters in the function, but the order of the two in the function is fixed: first, call the standard parameter, and then call the default parameter.
 

def a_rich_function(a, b, c, d=None, e=0):  pass

The reason is obvious: If we can place a default parameter before the standard parameter, the language will not be able to understand whether the default parameter has been initialized. For example, consider the following function definition
 

def a_rich_function(a, b, d=None, c, e=0):  pass

What parameters are input when the_rich_function (1, 2, 4, 5) function is called? Is it d = 4, c = 5, c = 4, e = 5? Because d has a default value. Therefore, the definition of this order is forbidden. If you do this, Python will throw a SyntaxError
 

>>> def a_rich_function(a, b, d=None, c, e=0):... pass... File "<stdin>", line 1SyntaxError: non-default argument follows default argument>>>

Default parameter evaluation

The default parameters can be improved by using common values or function call results, but the latter requires a special warning.

A common value is hard-coded. Therefore, the value is not required for compilation, but the function call is expected to evaluate the value at runtime. So we can write
 

import datetime as dt def log_time(message, time=dt.datetime.now()):  print("{0}: {1}".format(time.isoformat(), message))

Every time we call log_time (), we expect it to correctly provide the current time. Unfortunately, it is not successful: the default parameter is evaluated during definition (for example, when you import the module for the first time). The call result is as follows:
 

>>> log_time("message 1")2015-02-10T21:20:32.998647: message 1>>> log_time("message 2")2015-02-10T21:20:32.998647: message 2>>> log_time("message 3")2015-02-10T21:20:32.998647: message 3

If you assign the default value to an instance of the class, the result will be even more strange. You can go to Hitchhiker's Guide to Python! . .. The common solution is to replace the default parameter with None and check the parameter value within the function.
 
Conclusion

The default parameter can greatly simplify the API. You need to pay attention to its unique "failure point", that is, the time to evaluate the value. Surprisingly, function parameters and references are one of the most basic elements of Python, and sometimes are the same for experienced programmers. I suggest you take the time to learn about references and polymorphism.
Related reading:

  • OOP concepts in Python 2.x-Part 2
  • Python 3 OOP Part 1-Objects and types
  • Digging up Django class-based views-2
  • Python Generators-From Iterators to Cooperative Multitasking-2
  • OOP concepts in Python 2.x-Part 1

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.