Python Foundation-Function Parameters

Python Foundation-Function Parameters

Write in front

Unless otherwise specified, the following are based on Python 3

abstract
This paper introduces in detail various types of function parameters, including position parameters, default parameter values, keyword parameters, arbitrary parameter lists, named keyword parameters. It also introduces various ways of passing arguments when calling functions, including position parameters, keyword arguments, and using * and ** to unpack sequences and dictionaries.

1. Overview

Functions are created to some extent for reuse. If there is a very good code segment, which realizes the function of downloading network resources, if there is no function, it will be copied every time where the network resources need to be downloaded. Laziness is virtue. This code is abstracted as a function and called where it needs to be used.
The use of functions has the following advantages:

  • Increase code readability. For example, the download() function can be called where the network resources need to be downloaded, and the purpose of the program can be understood by name.
  • Increase code reusability. Compared with copying large blocks of code, the operability of calling functions is undoubtedly stronger.
  • Increase maintainability. If you need to change the implementation of download network resources, without the use of functions, you have to modify every practical download function, using functions, only need to modify the function;
  • Reduce the possibility of making mistakes. In the process of copying code, there will undoubtedly be some errors for various reasons, and the function will not.

Function definitions are very simple:

def func([formal_parameter1, ... formal_parameter1]):
    statement

The function definition above is to create a function object, and create a name func in the current scope, pointing to the function object. Within the scope of the scope, the name func can be used to call the function. When defining a function, the name in the parameter list is a function parameter, and the parameter used to call the function is an argument.

The parameters of Python function are very powerful, but they also pay a relatively complex price for this strength.

When defining a function, the formal parameters of a function can be of the following types:

  • positional parameters, the most commonly used form of parameter, position is more important than name.
  • The default argument values, in the form of param_name = argu_value, provide the default values for the parameters and must be placed after the position parameters.
  • arbitrary argument lists, * args form, args receive unmatched positional arguments in tuple form;
  • Keyword arguments, ** kwargs form, kwargs receive unmatched keyword arguments in the form of dictionary, keyword parameters need to be after any parameter list;
  • Named keyword-only arguments, after any list of parameters (or after a separate *), the call can only use keyword arguments.

When a function is called, arguments can be passed as follows:

  • Position parameters are matched from left to right according to position, and position is more important than name.
  • Keyword argument specifies the parameter value by specifying the name of the parameter. When calling, the key parameter must be after the position parameter, and the key parameter must be matched in the parameter list.
  • Unpack list / dictionary, use * (sequence) to unpack position arguments from the sequence, and use ** (dict) to unpack key arguments from the dictionary.

When these different parameters are combined, the list of function parameters will be quite complex. Always bear in mind that the matching of real parameters is the priority of position parameters. Moreover, any parameter list combined with keyword parameter list can match any way of function call.

2. Location parameters

Location parameter is the most common type of parameter, in which position is more important than name, because parameter matching is based on location:

# positional argument, name is not important, but order matters
def positional_argument(name, age):
    print('name->type:%s, value:%s' % (type(name), name))
    print('age->type:%s, value:%s' % (type(age), age))

When invoked, if the argument position is changed, the meaning is completely different:

positional_argument('Richard', 20)
positional_argument(20, 'Richard')

Position parameters and position parameters (collectively called position parameters) are the most important parameter types, and their priority is the highest in parameter matching.

3. Default values of parameters

People with experience in other high-level languages (such as java) know that overloaded functions have the same name, different parameter lists and different functions. The caller calls overloaded functions with different parameters by specifying different arguments.

But there is no way to overload functions in Python, because default parameters are worth it. Yes, callers can specify different parameters when calling the same function. Although overloading is not supported, Python implements overloading functions by default parameter values.

The parameters that specify the default parameter value cannot be located before the position parameter because the parameter matching is position-first. At this time, the parameters that specify the default value in front of the parameter will be overwritten by the position parameter, resulting in the latter position parameter can not match the parameter value and the call fails:

# default argument values, non-default argument cann't follow default argument
def default_argument_value(name, age = 20, id = '0001'):
    print('name->type:%s, value:%s' % (type(name), name))
    print('age->type:%s, value:%s' % (type(age), age))
    print('id->type:%s, value:%s' % (type(id), id))
    
# When invoked, there can be many forms of arguments
# Specify a unique mandatory parameter
default_argument_value('Richard')
# Specify one of the default parameters
default_argument_value('Richard', 22)
# Specify all parameters
default_argument_value('Richard', 22, '002')

4. Arbitrary parameter list

Python's function is more powerful than other high-level languages in that it can collect redundant unmatched parameters. Using parameters in the following format: * args, the actual parameters that have not been matched to the parameters are collected.

The additional position arguments received are stored as tuples, and the list of arbitrary parameters needs to follow the position parameters:

# Arbitrary Argument Lists
# It receives a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before **name.) 
# be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function

def arbitrary_arguments_list(name, age, *args):
    print('name->type:%s, value:%s' % (type(name), name))
    print('age->type:%s, value:%s' % (type(age), age))
    print('args->type:%s, value:%s' % (type(args), args))

# Arguments 1, 2, 3 have no location parameter matching and are collected by arbitrary parameter list.
arbitrary_arguments_list('Richard', 20, 1, 2, 3)

output:

name->type:<class 'str'>, value:Richard
age->type:<class 'int'>, value:20
args->type:<class 'tuple'>, value:(1, 2, 3)

4. Keyword parameters

When calling a function, it is not easy to find out which parameter each parameter matches by the way of position parameter, and then we can see the definition of the function. It can be invoked by specifying the corresponding parameters, so that the matching of parameters is more clear.

Or take the position parameter as an example:

# positional argument, name is not important, but order matters
def positional_argument(name, age):
    print('name->type:%s, value:%s' % (type(name), name))
    print('age->type:%s, value:%s' % (type(age), age))

It can be invoked by keywords:

# keyword arguments. 
# In a function call, keyword arguments must follow positional arguments. 
# All the keyword arguments passed must match one of the arguments accepted by the function, and their order is not important.
positional_argument(age = 20, name = 'Richard')

Keyword arguments must be followed by positional arguments and can be matched to parameter names in the parameter list, otherwise the call fails:

# There is no parameter named id in the parameter, so the call failed.
positional_argument(age = 20, name = 'Richard', id = '003')

Collect redundant keyword arguments
Arbitrary parameter list can receive parameters that are not matched to position parameters, while keyword parameter dictionary can accept parameters that are matched to keyword parameters. Through the way of ** kwargs, we collect the unmatched keyword arguments, and the keyword parameter dictionary should be after the location parameters:

# keyword arguments dict **kwargs.
# It receives a dictionary containing all keyword arguments except for those corresponding to a formal parameter.
def keyword_argument_dict(name, age, **kwargs):
    print('name->type:%s, value:%s' % (type(name), name))
    print('age->type:%s, value:%s' % (type(age), age))
    print('kwargs->type:%s, value:%s' % (type(kwargs), kwargs))
keyword_argument_dict(name = 'Richard', age = 20, id = '0001', type = 'it')

output:

name->type:<class 'str'>, value:Richard
age->type:<class 'int'>, value:20
kwargs->type:<class 'dict'>, value:{'id': '0001', 'type': 'it'}

In addition, the keyword dictionary needs to be after any parameter list.

4. Named keyword parameters

Arbitrary parameters appearing after * arg or * are named keyword parameters, which means that they can only be matched as keyword arguments, not location arguments.

# Keyword only argument.
# Any formal parameters which occur after the *args parameter are 'keyword-only' arguments,
# meaning that they can only be used as keywords rather than positional arguments.
def keyword_only_argument(name, *, age, id):
    print('name->type:%s, value:%s' % (type(name), name))
    print('age->type:%s, value:%s' % (type(age), age))
    print('id->type:%s, value:%s' % (type(id), id))

keyword_only_argument('Richard', age = 20, id = '001')

output:

name->type:<class 'str'>, value:Richard
age->type:<class 'int'>, value:20
id->type:<class 'str'>, value:001

5. Decomposition of Sequences and Dictionary Arguments

When a function is called, the sequence is unpacked as a positional argument using * sequence.
Use ** dict to unpack dictionaries as keyword arguments.

def mix_param(name, *args, **kwargs):
    print('name->type:%s, value:%s' % (type(name), name))
    print('args->type:%s, value:%s' % (type(args), args))
    print('kwargs->type:%s, value:%s' % (type(kwargs), kwargs))

mix_param('Richard', *(1, 2, 3), **{'age':20, 'id':'001'})

output:

name->type:<class 'str'>, value:Richard
args->type:<class 'tuple'>, value:(1, 2, 3)
kwargs->type:<class 'dict'>, value:{'age': 20, 'id': '001'}

Note that * args unpacking is a location parameter and ** kwargs unpacking is a keyword parameter, covering all possible parameter types in Python. Therefore, these two combinations can be used to call functions implemented by arbitrary parameters:

def foo(x, y, z, m = 0, n = 0):
    print(x, y, z, m, n)

def call_foo(*args, **kwargs):
    print('Call foo!')
    foo(*args, **kwargs)

Notice that in the call_foo function, args is a tuple and kwargs is a dictionary, so you can package them to call functions of arbitrary parameter form. This is a very useful way to call a parent constructor!

Keywords: Python network Java

Added by CharlesH on Mon, 17 Jun 2019 23:40:35 +0300