In-depth analysis of the parameters and scopes of functions in Python, python

Source: Internet
Author: User
Tags builtin

In-depth analysis of the parameters and scopes of functions in Python, python

PASS Parameters

Some brief key points when passing parameters in a function:

  • Parameter passing is achieved by automatically assigning an object to a local variable name. All parameters are actually transmitted through pointers, and objects passed as parameters are never automatically copied.
  • The parameter name assignment within the function does not affect the caller.
  • Changing the value of variable object parameters of a function will affect the caller.

In fact, the Python parameter passing model is quite similar to the C language:

Immutable parameters are passed through values. Objects such as integers and strings are referenced by objects rather than copied objects. However, it is impossible to change immutable objects in the original place, and the actual effect is similar to creating a copy.
A variable object is passed through a "Pointer. This means that the variable object can be modified inside the function.
> Avoid modifying variable parameters.
There are many ways to avoid parameter modification:

When passing parameters, pass a copy:

L = [1,2]changer(L[:])

Copy the function internally.

def changer(b): b=b[:]

Convert a mutable object to an immutable object

L=[1,2]changer(tuple(L))

> Simulate parameter output
There is a small trick for the return value of a parameter: Because return can return any type of objects, if these values are encapsulated into a tuples or other set types, it can also return multiple values.

def multiple(x,y): x = 2 y = [2,4] return x,y #Return new values in a tuple

This Code seems to return two values. In fact, there is only one: A tuples containing two elements, and its parentheses can be omitted.

Specific Parameter Matching Model

> Basic knowledge
Outline of Matching Model:

  • Position: match from left to right.
  • Keyword parameter: match by parameter name. (The caller can define which function accepts this value. By using the variable name of the parameter during the call, the name = value Syntax is used .)
  • Default parameter: defines the parameter value for a parameter without any input value.
  • Variable parameters: Collects any number of location-based or keyword-based parameters.
  • Variable Parameter unpacking: transmits any number of location-based or keyword-based parameters.
  • Keyword-only parameter: The parameter must be passed by name. (Only in Python3.0)

> Matching syntax

Syntax Location Explanation
Func (value) Caller Common parameters: match by location.
Func (name = value) Caller Keyword parameter: match by variable name.
Func (* sequence) Caller All objects are passed by name and used as independent location-based parameters.
Func (** dict) Caller Pass all the keywords/Values in pairs with names and use them as independent keyword parameters.
Def func (name) Function Common parameters: match by location or variable name.
Def func (name = value) Function Default parameter value, if it is passed in the call.
Def func (* name) Function Match and collect all parameters containing locations (in tuples.
Def func (** name) Function Match and collect all parameters containing locations (in the dictionary.
Def func (* args, name) Function Parameters must be passed by keyword in the call.
Def func (*, name = value) Function Parameters must be passed by keyword in the call. (Python3.0)

Description:

In the function call (the first four rows in the table), the variable name position is used for matching, but the name = value is used to tell Python to match according to the variable name, these are called keyword parameters. Using * sequence or ** dict in a call allows us to encapsulate any number of location-related or keyword objects in a sequence or dictionary, when they are passed to functions, they are unwrapped into separate, single parameters.
In the function header, a simple variable name is matched by location or variable name (depending on how the caller passes the parameter to it ), however, the default parameter value is defined in the form of name = value. * The form of name collects any extra unmatched parameters into the tuples, and ** the form of name will include additional phone keyword parameters in the dictionary. In Python3.0 and later versions, any formal or default parameter names after * name or a separate * are all keyword-only parameters, it must be passed by keyword during the call.
> Details
When using a mixed parameter model, Python will follow the following sequence rules.

In function calls, parameters must appear in this order: any position parameter (value) followed by a combination of any keyword parameter (name = value) and * sequence form, followed by the ** dict form.
In the function header, parameters must appear in this order: any common parameter (name) followed by any default parameter (name = value) followed by name (in Python3.0, followed by any name or name = value keyword-only parameter (in Python3.0), followed by the ** name form.
In the call and function header, if the ** arg form is displayed, it must all appear at the end.

In Python, the following steps are used to match parameters before values are assigned:

  • Assign non-Keyword parameters by location.
  • Assign a keyword parameter by matching the variable name.
  • Other additional non-keywords are allocated to * name tuples.
  • Other additional keyword parameters are assigned to the ** name dictionary.
  • Use the default value to assign parameters that are not assigned in the header.
  • After that, Python checks to ensure that only one value is input for each parameter. Otherwise, an error will occur. When all the matches are completed, Python assigns the objects passed to the parameter names to them.

> Keyword parameter and default parameter instance
If no special matching syntax is used, Python matches the variable name from left to right by default.

def f(a,b,c): print(a,b,c)f(1,2,3)   #Prints 1,2,3

Keyword Parameter

Keyword parameters can be matched by variable names, rather than by location.

f(c=3,b=2,a=1) #Prints 1,2,3

Default parameters

Default parameters allow you to create optional parameters for a function. If no value is input, the parameter is assigned a default value before the function is run.

def f(a,b=2,c=3): print(a,b,c)f(1)    #Prints 1,2,3f(1,4)   #Prints 1,4,3f(1,c=6)   #Prints 1,2,6

Mix keyword parameters with default parameters

def func(spam,eggs,totast=0,ham=0): print((spam,eggs,totast=0,ham=0))func(1,2)     #Ouput:(1,2,0,0)func(1,ham=1,eggs=0)  #Ouput:(1,0,0,1)func(spam=1,eggs=0)   #Ouput:(1,0,0,0)func(toast=1,eggs=2,spam=3) #Ouput:(3,2,1,0)func(1,2,3,4)    #Ouput:(1,2,3,4)

> Any parameter instance
The last two matching extensions, * and **, allow the function to receive any number of parameters.

Collection Parameters

In Function Definition, unmatched location parameters are collected in tuples.

def f(*args):print(args)

When this function is called, Python collects all location-related parameters into a new tuples and assigns the tuples To The args variable. Therefore, it is a common tuples object that can be indexed or iterated.

** Features are similar, but they are only valid for keyword parameters. These keyword parameters are passed to a new dictionary, which can be processed by common dictionary tools. In this case, ** you can convert a keyword parameter to a dictionary. You can use a key call later to perform step-by-step or dictionary iteration.

def f(a,*pargs,**kargs):print(a,pargs,kargs)f(1,2,3,x=1,y=2)  #Prints:1 (2,3) {'x':2,'y':1}

Unpack Parameters

In the latest Python version, we can use the * syntax when calling a function. In this case, it is opposite to the function definition. It unpacks the set of parameters instead of the set of parameters.

def func(a,b,c,d):print(a,b,c,d)args=(1,2)args+=(3,4)func(*args)   #Prints 1,2,3,4

Similarly, when a function is called, ** unpacks a dictionary in the form of a key/value pair to make it an independent keyword parameter.

args={'a':1,'b':2,'c':3}args['d']=4func(**args)   #Prints 1,2,3,4

Note: Do not confuse the */** syntax of the function header and function call: in the header, it means to collect any number of parameters, while in the call, it unpacks any number of parameters.

Versatility of application functions

if <test>: action,args=func1,(1,)else: action,args=func2,(1,2,3)...action(*args)

> Python3.0 Keyword-Only Parameter
Python3.0 generalized the sorting rules of the function header, allowing us to specify the keyword-only parameter-that is, the parameter must only be passed according to the keyword and will not be filled by a location parameter.

In terms of syntax, the keyword-only parameter is encoded as the named parameter and appears after * args In the parameter list. All these parameters must be passed using the keyword syntax in the call.

We can also use a * character in the parameter list to indicate that a function does not accept a variable length parameter list, but still expects all parameters following * to be passed as keywords.

def kwonly(a,*,b,c): print(a,b,c)kwonly(1,c=3,b=2) #Prints:1,2,3kwonly(c=3,b=2,a=1) #Prints:1,2,3kwonly(1,2,3)  #Error!

In the above Code, B and c must be passed according to the keyword, and other additional locations are not allowed to be passed.

In addition, the default function is still valid for the keyword-only parameter. Therefore, the keyword-only parameter with the default value is optional. However, the keyword-only parameter without the default value is actually the keyword-only parameter required by the function.

At the end of the sorting rule, note that the keyword-only parameter must be specified after a single asterisk, instead of two asterisks. The named parameter cannot appear after any keyword format of ** args, and a ** cannot appear in the parameter list alone. These two methods will produce errors.

def kwonly(a,**pargs,b,c)  #Error!def kwonly(a,**,b,c)   #Error!

This means that in the header of a function, the keyword-only parameter must be written before any keyword form of ** args, and after any location form of * args.

In fact, in function calls, similar sorting rules are also true: When the keyword-only parameter is passed, they must appear before a ** args form. The keyword-only parameter can be written before or after * arg, and may be included in ** args:

def f(a,*b,c=6,**d):print(a,b,c,d)f(1,*(2,3),**dict(x=4,y=5))  #Prints:1 (2,3) 6 {'x':4,'y':5}f(1,*(2,3),**dict(x=4,y=5),c=7) #Error!f(1,*(2,3),c=7,**dict(x=4,y=5)) #Prints:1 (2,3) 7 {'x':4,'y':5}f(1,c=7,*(2,3),**dict(x=4,y=5)) #Prints:1 (2,3) 7 {'x':4,'y':5}f(1,*(2,3),**dict(x=4,y=5,c=7)) #Prints:1 (2,3) 7 {'x':4,'y':5}

Python Scope

When a Python program only uses a variable name, Python creates, modifies, or searches for the variable name in the so-called namespace (where the variable name is saved. That is to say, in the Code, the location where the variable name is assigned determines the accessible range of the variable name, that is, the namespace in which it exists.

In addition to the package, the function also adds an additional namespace layer for the Program: by default, all variable names of a function are associated with the namespace of the function. This means:

A variable defined in def can be used in the code in def, and such a variable name cannot be applied outside the function.
The names of variables in def do not conflict with those other than def. A variable X assigned outside def is a completely different variable from the variable X assigned in def.
> Scope rules
Before writing a function, all the code we write is at the top of a module (that is, not nested in def ), therefore, the variable names we use either exist in the module File or are pre-defined in Python. The function defines the local scope, while the module defines the global scope. The two scopes have the following relationships:

An embedded module is a global scope. Each module is a global scope (that is, a namespace created at the top of the module file ). For external modules, the global variables of this module become the attributes of this module object, but this module can be used like simple variables.
The scope of global scope is limited to a single file. The global scope refers to the variable name at the top of a file. It is only global for the code in this file. In Python, there is no global scope based on a single, all-encompassing scenario file.
Each function call creates a new local scope.
The assigned variable name is a local variable unless declared as a global variable or a non-local variable.
All variable names can be classified as local, global, or built-in
> Variable name parsing: LEGB Principle
Python's variable name parsing mechanism is sometimes called the LEGB rule. When an unauthenticated variable name is used in a function, Python searches for four scopes:

  • Local scope (L)
  • Local scope (E) of def or lambda in the previous layer (in fact, nested functions)
  • Global scope (G)
  • Finally, built-in scope (B)

Python searches for variables in the preceding four scopes sequentially and stops at the first place where the variable name can be found. If the variable name is not found in these four scopes, Python reports an error.

It should be emphasized that the above four scopes are the code search process in the function. That is to say, you can directly use the variables in the previous layer in the function!

s=10def times(x,y): x=s return x*ytimes(3,4) #return 40 not 12

> Built-in Scope
The built-in scope is implemented through a standard module named builtin, but this variable name is not included in the built-in scope itself, so you must import this file to use it. In Python3.0, you can use the following code to check which variables are predefined:

import builtinsdir(builtins)

Therefore, there are actually two ways to reference a built-in function: benefit from the LEGB rule, or manually import the builtin module. The second method is useful in some complex tasks, because some local variables may overwrite the built-in variables or functions. Again, the LEGB rule takes effect only for the first place where the variable name is located!

Global Statement

The global statement is a namespace declaration that tells the Python interpreter to generate one or more global variables, that is, the variable names that exist in the internal scope (namespace) of the entire module. About the global variable name:

The global variable is the variable name located at the top layer of the module File.
If a global variable is assigned a value inside the function, it must be declared.
The global variable name can be referenced in the function without being declared.
The global statement contains the keyword global, followed by one or more variable names separated by commas. When a function topic is assigned or referenced, all the listed variables will be mapped to the scope of the entire module. For example:

X=88def func(): global X X = 99func()print(X) #Prints 99

Scope and nested Functions

This part is about the layer e in the LEGB search rule, which includes the local scope of any nested function. Nested scopes are sometimes called static nested scopes. In fact, nesting is a syntax nested scope, which corresponds to the physical structure of the program source code.

> Details of nested scopes
For a function:

A reference (X) First searches for the variable name X in the local (function) Scope, and then searches for the local scope in the function nested in the code syntax from the inside out; then find the current global scope (module File), and finally within the built-in scope (module builtin ). The global declaration will be searched directly from the global (module File) scope. In fact, it starts from referencing X and goes through a layer of online search until the first X is found.
By default, a value assignment (X = value) creates or modifies the current scope of variable name X. If X is declared as a global variable within the function, it will create or change the variable name X to the scope of the entire module. On the other hand, if X is declared as nonlocal in the function, the value assignment modifies the name X in the local scope of the nearest nested function.
> Examples of nested scopes

X = 99def f1(): X = 88 def f2(): print(X) f2()f1() #Prints 88:enclosing def local

The preceding code is valid. def is a simple execution statement that can appear in any other statement, including nested in another def. In the code, f2 is a function defined in f1. In this case, f2 is a temporary function, only exists in the internal execution process of f1 (and only visible to the Code in f1 ). By using the LEGB search rule, X in f2 is automatically mapped to X in f1.

It is worth noting that this nested scope search is also valid after the nested function has been returned.

X = 99def f1(): X = 88 def f2(): print(X) #Remember X in enclosing def scope return f2 #Return f2 but don't call itaction = f1() #Make return functionaction() #Call it now:Prints 88

In the above Code, no matter how many calls to the action function, the return value is 88. f2 remembers X in the nested scope of f1, although f1 is no longer in the active status.

Factory Functions

These actions are sometimes called closure or factory functions-a function that can remember the value of a variable in a nested scope, even if that scope may no longer exist. Generally, it is better to use classes to record state information, but factory functions like this also provide an alternative. Example:

def maker(N): def action(X): return X ** N return actionf=maker(2) #Pass 2 to Nf(3) #Pass 3 to X,N remembers 2: 3**2,Return 9f(4) #return 4**2g=maker(3) #g remembers 3,f remembers 2g(3) #return 27f(3) #return 9

From the code above, we can see that the f and g functions respectively record different N values, that is, they record different States. Each time they assign values to the factory function, A set of State information is obtained. Each function has its own state information, which is maintained by the variable N in the maker.

The scope is compared with the default parameters with cyclic variables.

There is a special case worth noting in the given rule: if lambda or def are defined in a function and nested in a loop, and the nested function references a variable of the upper scope, this variable is changed by the loop, and all functions generated in this loop will have the same value-the value of the variable referenced when the last loop is completed. Example:

def makeActions(): acts=[] for i in range(5): #Tries to remember each i acts.append(lambda x: i ** x) #All remember same last it return acts

Although you are trying to create a function list so that each function has different State values, in fact, the State values of the functions in this list are the same, which is 4. Because variables in the nested scope are searched only when nested functions are called, they actually remember the same values (the values of variable loops in the last loop iteration ).

To make this type of code work, you must use the default parameter to pass the current value to the variable in the nested scope. Because the default parameters are evaluated when nested functions are created (rather than called later), each function remembers its own variable I value.

def makeActions(): acts=[] for i in range(5): #Use default instead acts.append(lambda x,i=i: i ** x) #Remember current i return acts{

Nonlocal statement

In fact, in Python3.0, we can also modify nested scope variables as long as we declare them in a nonlocal statement. Using this statement, the nested def can read and write the name in the nested function. Nonlocal is applied to a name in the scope of a nested function, instead of the global module scope beyond def-they may only exist in a nested function, and cannot be created by the first value assignment in a nested def.

In other words, nonlocal allows assignment of name variables in the nested function scope, and restricts such name scope lookup to the nested def.

> Nonlocal Basics

def func(): nonlocal name1,name2...

This statement allows a nested function to modify one or more names defined in the scope of a syntax nested function. In Python 2.x, when a function def is nested in another function, nested functions can reference various variables defined in the previous function, but cannot modify them. In Python3.0, the nested scope is declared in a nonlocal statement, so that nested functions can be assigned values and such names can be modified accordingly.

In addition to allowing you to modify the name in the nested def, the nonlocal statement also speeds up reference-just like the global statement, nonlocal enables the query of the names listed in the statement to start from the scope of the nested def, rather than from the local scope of the declared function. That is to say, nonlocal also means "completely skipping my local scope ".

In fact, when a nonlocal statement is executed, the names listed in nonlocal must be defined in a nested def. Otherwise, an error occurs. The direct effect is similar to that of global: global means that the names are in the modules of the previous layer, and nonlocal means that they are in the def function of the previous layer. Nonlocal is even stricter-scope lookup is limited to nested def. That is to say, nonlocal can only appear in nested def, but not in the global scope of the module or the built-in scope outside def.

When used in a function, both global and nonlocal statements limit the search rules to some extent:

Global enables the scope query to start from the scope of the nested module and allows the assignment of the name. If the name does not exist in the module, the scope lookup continues to the built-in scope. However, the value of global names is always created or modified in the module scope.
Nonlocal restricted scope lookup is only a nested def, requiring that names already exist and allow assignments to them. Scope lookup does not continue to the global or built-in scope.
> Nonlocal Application
Use nonlocal to modify

def tester(start): state = start #each call gets its own state def nested(label): nonlocal state #remember state in enclosing scope print(label,state) state+=1 #Allowed to change it if onolocal return nestedF = tester(0) #Increments state on each callF('spam') #Prints:spam 0F('ham') #Prints:ham 1F('eggs') #Prints:eggs 2

Boundary Condition

When a nonlocal statement is executed, the nonlocal name must have been assigned a value in a nested def scope. Otherwise, an error is returned.
Nonlocal restricted scope lookup is only for nested def, and nonlocal does not look up in the global scope of the nested module or all built-in scopes other than def.

Articles you may be interested in:
  • Summary of the usage of functions in Python Programming
  • Analysis on function decorators written in Python
  • Examples of function (closure) usage in Python Functions
  • The example explains how to call and define functions in Python.
  • In-depth introduction to the use of parameters in Python functions and the traps of default parameters
  • Use Python built-in modules and functions to convert numbers in different hexadecimal formats
  • Usage Analysis of element traversal using the enumerate function in python
  • Exploring the use of open functions in python
  • Python nested functions use external function variables (Python2 and Python3)
  • Use * args and ** kwargs in Python functions to pass variable length parameters
  • Analysis of Function Definition instances in python Development

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.