function

The third function parameter

1. Position parameters

def power(x):
    return x * x 

For power(x)functions, the parameter xis a positional parameter.

power(x)Change it to , power(x, n)used to calculate x^n:

def power(x, n):
    s = 1 while n > 0: n = n - 1 s = s * x return s 

For this modified power(x, n)function, any n-th power can be computed:

>>> power(5, 2)
25
>>> power(5, 3) 125 

The modified power(x, n)function has two parameters: xand , both of which are positional parameters. When calling the function, the two incoming values ​​are assigned to the parameters and nin the order of their positions .xn

 

2. Default parameters

There is no problem with the new power(x, n)function definition, however, the old calling code fails because we have added a parameter and the old code cannot be called properly because of a missing parameter:

>>> power(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: power() missing 1 required positional argument: 'n'

Python's error message is clear: The calling function is power()missing a positional argumentn

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

In this way, when we call power(5), it is equivalent to calling power(5, 2):

>>> power(5)
25
>>> power(5, 2) 25 

For n > 2other cases, n must be passed in explicitly, eg power(5, 3).

As you can see from the above example, default parameters can simplify function calls. There are a few things to keep in mind when setting default parameters:

One is that the mandatory parameters come first, and the default parameters come after, otherwise the Python interpreter will report an error (think about why the default parameters cannot be placed in front of the mandatory parameters);

The second is how to set the default parameters.

When the function has multiple parameters, put the parameters with large changes in the front, and put the parameters with small changes in the back. Parameters with small changes can be used as default parameters.

What are the benefits of using default parameters? The biggest advantage is that it can reduce the difficulty of calling functions.

Note: One thing to keep in mind when defining default parameters: default parameters must point to immutable objects!

To modify the above example, we can do it with Nonethis immutable object:

def add_end(L=None):
    if L is None: L = [] L.append('END') return L 

Now, no matter how many times it is called, there is no problem:

>>> add_end()
['END']
>>> add_end()
['END']

Why design str, Nonesuch immutable objects? Because once an immutable object is created, the data inside the object cannot be modified, which reduces errors caused by modifying data. In addition, since the object does not change, reading the object at the same time in a multitasking environment does not need to be locked, and there is no problem with reading at the same time. When we write a program, if we can design an immutable object, we should try to design it as an immutable object.

 

3. Variable parameters

function with variable number of arguments

def calc(*numbers):
    sum = 0 for n in numbers: sum = sum + n * n return sum

Defining a variable parameter is compared to defining a list or tuple parameter by simply prefixing the parameter with a *number. Inside the function, the parameter numbersreceived is a tuple, so the function code is completely unchanged. However, when calling this function, you can pass in any number of parameters, including 0 parameters:

>>> calc(1, 2)
5
>>> calc() 0

What if you already have a list or tuple and you want to call it with a variadic argument? This can be done like this:

>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2]) 14 

This way of writing is of course feasible, but the problem is too cumbersome, so Python allows you to add a *number in front of the list or tuple, and pass the elements of the list or tuple into variable parameters:

>>> nums = [1, 2, 3]
>>> calc(*nums) 14 

*numsIndicates that numsall elements of this list are passed in as variable parameters. This notation is quite useful and common

 

4. Keyword Parameters

Variable parameters allow you to pass in zero or any number of parameters, which are automatically assembled into a tuple when the function is called. And keyword parameters allow you to pass in 0 or any number of parameters with parameter names, these keyword parameters are automatically assembled into a dict inside the function

def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)

What are keyword arguments for? It can extend the functionality of the function. For example, in the personfunction, we are guaranteed to receive nameand agethese two parameters, but if the caller is willing to provide more parameters, we can also receive. Imagine that you are doing a user registration function. Except for the user name and age, which are required, the others are optional. Using keyword parameters to define this function can meet the registration requirements.
>>> extra = {'city': 'Beijing', 'job': 'Engineer'} >>> person('Jack', 24, **extra) name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

**extraIndicates that extraall key-values ​​of this dict are passed into the parameters of the function with keyword parameters **kw, and kwa dict will be obtained. Note that kwthe obtained dict is extraa copy, and kwthe correct changes will not affect the functions outside the function.extra

5. Named keyword arguments

For keyword arguments, the caller of the function can pass in any unrestricted keyword arguments. As for what is passed in, it needs to be kwchecked inside the function.

If you want to restrict the names of keyword arguments, you can use named keyword arguments, for example, only accept cityand jobas keyword arguments. The functions defined in this way are as follows:

def person(name, age, *, city, job):
    print(name, age, city, job)

Unlike keyword arguments **kw, named keyword arguments require a special separator, *and *subsequent arguments are treated as named keyword arguments.

The calling method is as follows:

>>> person('Jack', 24, city='Beijing', job='Engineer') Jack 24 Beijing Engineer

If there is already a variadic parameter in the function definition, the following named keyword arguments no longer need a special separator *:

def person(name, age, *args, city, job):
    print(name, age, args, city, job)

Named keyword arguments must be passed in the parameter name, unlike positional arguments. If no parameter name is passed in, the call will report an error:

>>> person('Jack', 24, 'Beijing', 'Engineer')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: person() takes 2 positional arguments but 4 were given

Due to the lack of parameter names cityand parameters in the call job, the Python interpreter treats all 4 parameters as positional parameters, but the person()function only accepts 2 positional parameters.

Named keyword arguments can have default values ​​to simplify invocation:

def person(name, age, *, city='Beijing', job): print(name, age, city, job) 

Since named keyword parameters cityhave default values, you can call without cityparameters:

>>> person('Jack', 24, job='Engineer')
Jack 24 Beijing Engineer 

When using named keyword arguments, pay special attention, if there are no variadic arguments, you must add one *as a special separator. If missing *, the Python interpreter will not recognize positional and named keyword arguments:

6. Parameter combination

With a tuple and dict, you can also call the above functions:

>>> args = (1, 2, 3, 4) >>> kw = {'d': 99, 'x': '#'} >>> f1(*args, **kw) a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'} >>> args = (1, 2, 3) >>> kw = {'d': 88, 'x': '#'} >>> f2(*args, **kw) a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'} 

So, for any function, it can be func(*args, **kw)called in a similar fashion, no matter how its parameters are defined.

summary

Python functions have a very flexible parameter form, which can implement simple calls or pass in very complex parameters.

The default parameter must be an immutable object. If it is a mutable object, there will be a logic error when the program runs!

Note the syntax for defining variadic and keyword arguments:

*argsis a variable parameter, and args receives a tuple;

**kwis a keyword parameter, and kw receives a dict.

And the syntax for how to pass in variadic and keyword arguments when calling a function:

Variable parameters can be directly passed in: func(1, 2, 3), or you can assemble a list or tuple first, and then *argspass in: func(*(1, 2, 3));

Keyword arguments can either be passed in directly: func(a=1, b=2), or you can assemble the dict first, and then **kwpass in: func(**{'a': 1, 'b': 2}).

Using *argsand **kwis the idiom of Python, of course, other parameter names can also be used, but it is better to use the idiom.

Named keyword arguments are meant to limit the parameter names that the caller can pass in, and to provide default values.

Define named keyword arguments. Don't forget to write the delimiter when there are no variadic arguments *, otherwise the definition will be a positional argument.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324484584&siteId=291194637