Parameters of 07-02 function

Keywords: Python less

[TOC]

Introduction of Participating Arguments in One Form

Illustration: Fig. 05

The parameters of a function are divided into formal and actual parameters, referred to as formal and actual parameters:

A formal parameter is a parameter declared in parentheses when a function is defined.A formal parameter is essentially a variable name that receives values from outside.

Arguments are the values passed in parentheses when a function is called, which can be a constant, a variable, an expression, or a combination of the three:

#1: Arguments are constants
res=my_min(1,2)

#2: Arguments are variables
a=1
b=2
res=my_min(a,b)

#3: Arguments are expressions
res=my_min(10*2,10*my_min(3,4))

#4: Arguments can be any combination of constants, variables, and expressions
a=2
my_min(1,a,10*my_min(3,4))

When a parametric function is called, the argument (value) is assigned to the parameter (variable name).In Python, variable names and values are purely binding relationships, whereas for functions, such binding relationships only take effect at the time of a function call and are released at the end of the call.

Illustration: Fig. 06

Specific Use of Dimorphic Participating Arguments

2.1 Location parameters

Location is order. Location parameters refer to parameters defined in order and need to be viewed from two perspectives:

  1. When defining a function, a parameter is defined in left-to-right order, called a position parameter. Any parameter defined in this form must be passed in a value.

    >>> def register(name,age,sex): #Define position parameters: name, age, sex, all three must be passed values
    ...     print('Name:%s Age:%s Sex:%s' %(name,age,sex))
    ... 
    >>> register() #TypeError: Three position parameters are missing
  2. When a function is called, arguments are defined in left-to-right order, called positional arguments. Arguments defined in this form correspond to the formal parameters in left-to-right order.

    >>> register('lili',18,'male') #The corresponding relationships are: name='lili', age=18,sex='male'
    Name:lili Age:18 Sex:male

Illustration: Fig. 07

2.2 Keyword Parameters

When a function is called, arguments can be in the form of key=value, called keyword parameters. Arguments defined in this form can be defined completely out of left-to-right order, but can still be assigned values to specified parameters.

>>> register(sex='male',name='lili',age=18)
Name:lili Age:18 Sex:male

It is important to note that when calling a function, arguments can also be mixed by location or by keyword, but you must ensure that the keyword parameter follows the position parameter and that you cannot assign a parameter repeatedly

>>> register('lili',sex='male',age=18) #Use correctly
>>> register(name='lili',18,sex='male') #SyntaxError: Keyword parameter name='lili'precedes position parameter 18
>>> register('lili',sex='male',age=18,name='jack') #TypeError: The parameter name is repeatedly assigned

Illustration: Fig. 08

##2.3 default parameters

When defining a function, parameters are already assigned values, which are called default parameters. When a function has multiple parameters, parameters whose values change frequently need to be defined as positional parameters, while parameters whose values change less need to be defined as default parameters.For example, if you write a function that registers student information and the majority of students are male, you can define the parameter sex as the default parameter

>>> def register(name,age,sex='male'): #The default sex value is male
...     print('Name:%s Age:%s Sex:%s' %(name,age,sex))
...

The parameter sex is already assigned at definition time, meaning that it can be called without assigning sex, which reduces the complexity of function calls

>>> register('tom',17) #In most cases, there is no need to pass a value for sex, defaulting to male
Name:tom Age:17 Sex:male
>>> register('Lili',18,'female') #In rare cases, you can pass a value of female for sex
Name:Lili Age:18 Sex:female

Illustration: Fig. 09

Note:

  1. Default parameter must follow location parameter
  2. The value of the default parameter is assigned only once during the function definition phase
>>> x=1
>>> def foo(arg=x):
...     print(arg)
... 
>>> x=5 #The definition phase arg has been assigned a value of 1, and the modification here has nothing to do with the default parameter arg
>>> foo()
1
  1. The value of the default parameter should normally be set to an immutable type

    >>> def foo(n,arg=[]):
    ...     arg.append(n)
    ...     return arg
    ... 
    >>> foo(1)
    [1]
    >>> foo(2)
    [1, 2]
    >>> foo(3)
    [1, 2, 3]

    Each call adds value to the same list from the previous one, modified as follows

    >>> def foo(n,arg=None):
    ...     if arg is None:
    ...         arg=[]
    ...     arg.append(n)
    ...     return arg
    ... 
    >>> foo(1)
    [1]
    >>> foo(2)
    [2]
    >>> foo(3)
    [3]

Illustration: Joke Fig. 10

##2.4 Variable length parameters (* and ** usage)

Variable parameter length means that when a function is called, the number of arguments may not be fixed, and when a function is called, arguments are defined either by location or by keyword, which requires that the parameter provide two solutions for dealing with two forms of variable length parameters

2.4.1 Position parameter with variable length

If the last parameter is preceded by a plus sign, the overflow position argument is received when the function is called and saved as a tuple and assigned to it

>>> def foo(x,y,z=1,*args): #Add * before the last parameter name args
...     print(x)
...     print(y)
...     print(z)
...     print(args)
... 
>>> foo(1,2,3,4,5,6,7)  #Arguments 1, 2, 3 are assigned parameters x, y, z by location. The extra positional arguments 4, 5, 6, 7 are * received, saved as tuples, and assigned to args, that is, args=(4, 5, 6,7)

1
2
3
(4, 5, 6, 7)

If we've generated a list beforehand, we can still pass values to *args

>>> def foo(x,y,*args):
...     print(x)
...     print(y)
...     print(args)
... 
>>> L=[3,4,5]
>>> foo(1,2,*L) # *L equals position parameter 3,4,5, foo(1,2,*L) equals foo(1,2,3,4,5)
1
2
(3, 4, 5)

Illustration: Hoax Fig. 11

Note: If you pass in L without adding a *, then L is just a common location parameter

>>> foo(1,2,L) #Only one more position argument L
1
2
([1, 2, 3],)

If the formal parameter is a regular parameter (position or default), the argument can still be in the form of *

>>> def foo(x,y,z=3):
...     print(x)
...     print(y)
...     print(z)
... 
>>> foo(*[1,2]) #Equivalent to foo(1,2)
1
2
3

If we want to sum several values, *args will come in handy.

>>> def add(*args):
...     res=0
...     for i in args:
...         res+=i
...     return res
... 
>>> add(1,2,3,4,5)
15

Illustration: Fig. 12

2.4.2 Variable length keyword parameters

If the last parameter is preceded by a plus sign, the overflowed keyword parameter is received when the function is called and saved as a dictionary and assigned to it

>>> def foo(x,**kwargs): #Add** before the last parameter kwargs
...     print(x)        
...     print(kwargs)   
... 
>>> foo(y=2,x=1,z=3) #The overflow keyword argument y=2, z=3 is received by **, saved as a dictionary and assigned to kwargs
1
{'z': 3, 'y': 2}

If we generated a dictionary beforehand, we could still pass values to **kwargs

>>> def foo(x,y,**kwargs):
...     print(x)
...     print(y)
...     print(kwargs)
... 
>>> dic={'a':1,'b':2} 
>>> foo(1,2,**dic) #**dic is equivalent to keyword parameter a=1, b=2, foo(1,2,**dic) is equivalent to foo(1,2,a=1,b=2)
1
2
{'a': 1, 'b': 2}

Illustration: Hoax Fig. 13

Note: If no ** is added to the incoming dic, the DIC is only a common location parameter

>>> foo(1,2,dic) #TypeError: Function foo only takes two positional arguments, but passes three

If the parameter is a regular parameter (position or default), the argument can still be in the form of **

>>> def foo(x,y,z=3):
...     print(x)
...     print(y)
...     print(z)
... 
>>> foo(**{'x':1,'y':2}) #Equivalent to foo(y=2,x=1)
1
2
3

If we were to write a user-authenticated function, it would be possible to start with user-name-password-based authentication only. We could use **kwargs to provide a good environment for future extensions while maintaining the simplicity of the function.

>>> def auth(user,password,**kwargs): 
...     pass 
...

2.5 Named Keyword Parameters

Once the **kwargs parameter is defined, the function caller can pass in any key parameter key=value, and if the execution of the function body code depends on a key, it must be judged within the function

>>> def register(name,age,**kwargs):
...     if 'sex' in kwargs:
...         #With sex parameter
...         pass
...     if 'height' in kwargs:
...         #With height parameter
...         pass
... 

To qualify the caller of a function to pass a value in the form of key=value, Python3 provides a special syntax: the parameter needs to be defined as a delimiter, followed by a number called a named keyword parameter.For such parameters, when a function is called, the value must be passed as key=value and must be passed

>>> def register(name,age,*,sex,height): #sex,height is the named keyword parameter
...     pass
... 
>>> register('lili',18,sex='male',height='1.8m') #Use correctly
>>> register('lili',18,'male','1.8m') # TypeError: Pass values for sex and height without using keywords
>>> register('lili',18,height='1.8m') # TypeError does not pass a value for the named keyword parameter height.

Illustration: Joke Fig. 14

Named keyword parameters can also have default values to simplify calls

>>> def register(name,age,*,sex='male',height):
...     print('Name:%s,Age:%s,Sex:%s,Height:%s' %(name,age,sex,height))
... 
>>> register('lili',18,height='1.8m')
Name:lili,Age:18,Sex:male,Height:1.8m

It should be emphasized that sex is not the default parameter and height is not the location parameter, because both are behind, so they are named keyword parameters. The parameter sex='male'is the default value of named keyword parameters, so even before the parameter heights, there is no problem.In addition, if the parameter already has an args, the named keyword parameter no longer needs a separate * as the delimiter

>>> def register(name,age,*args,sex='male',height):
...   print('Name:%s,Age:%s,Args:%s,Sex:%s,Height:%s' %(name,age,args,sex,height))
... 
>>> register('lili',18,1,2,3,height='1.8m') #sex and height are still named keyword parameters
Name:lili,Age:18,Args:(1, 2, 3),Sex:male,Height:1.8m

Illustration: Fig. 15, 16

2.6 Combination Use

In summary, all the above parameters can be used in any combination, but they must be defined in the following order: position parameter, default parameter, *args, named keyword parameter, **kwargs

Variable parameter *args is usually used in combination with keyword parameter *kwargs. If the formal parameters of a function are args and **kwargs, it means that the function can accept any form of parameter of any length

>>> def wrapper(*args,**kwargs):
...     pass
...

Illustration: Joke Fig. 17

Inside the function, you can also pass the parameters you receive to another function (which is useful in the implementation of the 4.6 subsection decorator)

>>> def func(x,y,z):
...     print(x,y,z)
... 
>>> def wrapper(*args,**kwargs):
...     func(*args,**kwargs)
...
>>> wrapper(1,z=3,y=2)
1 2 3

As mentioned above, when passing parameters to function wrapper, the parameter rules of function func are followed. The process of calling function wrapper is analyzed as follows:

  1. Positional argument 1 is * received, saved as tuples, assigned to args, that is, args=(1,), key argument z=3, y=2 is ** received, saved as a dictionary and assigned to kwargs, that is, kwargs={'y': 2,'z': 3}
  2. Executing func(args,kwargs), that is, func (*(1,), ** {'y': 2,'z': 3}), is equivalent to func(1,z=3,y=2)
Tip: There is no syntax error in replacing args and kwargs in *args,**kwargs with other names, but it is customary to use args and kwargs.

Illustration: Joke Fig. 18

Posted by pug on Tue, 24 Dec 2019 13:16:56 -0800