Deep analysis of parameters and scopes of functions in Python

Source: Internet
Author: User
Tags builtin unpack
Passing Parameters

Some brief key points when a function passes a parameter:

    • The argument is passed by automatically assigning the object to the local variable name. All parameters are actually passed by pointers, and objects passed as parameters are never automatically copied.
    • The assignment of the parameter name inside the function does not affect the caller.
    • Changing the value of a variable object parameter to a function will have an effect on the caller.

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

The immutable parameter is passed by value. Objects such as integers and strings are made by object references rather than copies, but because it is impossible to change immutable objects in their original place, the actual effect is much like creating a copy.
A mutable object is passed through a "pointer". This means that mutable objects can be modified inside the function.
>> avoid changes to variable parameters
There are many ways to avoid modifying parameters:

When passing parameters, pass a copy:

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

Copy inside the function

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

Convert a Mutable object to an immutable object

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

>> simulation of parametric outputs
There is a small tip for the return value of a parameter: Because return can return any kind of object, it can also return multiple values if the values are encapsulated into a tuple or other collection type.

def multiple (x, y): × = 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 tuple containing 2 elements, its parentheses can be omitted.

A specific parameter matching model

>> Basic Knowledge
Outline of the matching model:

    • Position: Match from left to right.
    • Keyword parameter: match by parameter name. (The caller can define which function accepts this value, using the Name=value syntax by using the variable name of the parameter at the time of the call.) )
    • Default parameter: Defines a parameter value for a parameter that does not have an incoming value.
    • Variable parameter: Collects any number of parameters based on location or keyword.
    • Variable parameter unpacking: Pass any number of parameters based on the location or keyword.
    • Keyword-only parameter: The parameter must be passed by name. (only available in Python3.0)

>> Match Syntax

Grammar location explain
Func (value) Called by General parameters: match by location.
Func (Name=value) Called by Keyword parameter: match by variable name.
Func (*sequence) Called by All objects are passed as name and are independent location-based parameters.
Func (**dict) Called by All keywords/values are passed as name pairs, and are used as independent keyword parameters.
def func (name) Function General parameters: Match by position or variable name.
def func (Name=value) Function The default parameter value, if passed in the call.
def func (*name) Function Matches and collects (in tuples) all parameters that contain locations.
def func (**name) Function Matches and collects (in the dictionary) all parameters that contain locations.
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)

The corresponding description:

In the call of the function (the first 4 rows in the table), a simple match is made by the position of the variable name, but using the form of Name=value tells Python to match the variable name, which is called the keyword argument. Using *sequence or **dict in a call allows us to encapsulate any number of positional related or keyword objects appropriately in a sequence or dictionary, and unpack them as separate, single arguments when passing them to a function.
In the function's head, a simple variable name is matched by a position or variable name (depending on how the caller passed it to it), but the default parameter value is defined by the Name=value form. The *name form collects arbitrary additional mismatched parameters into the tuple, and the **name form will be the phone's extra keyword argument into the dictionary. In Python3.0 and later versions, any formal or default parameter names followed by *name or a separate * are keyword-only parameters and must be passed by keyword at the time of invocation.
>> Details
When using a mixed parametric model, Python will follow the following rules about order.

In a function call, the arguments must appear in this order: any positional parameter (value) followed by any combination of keyword arguments (name=value) and *sequence, followed by the **dict form.
On the function head, the arguments must appear in this order: any general parameter (name) followed by any default parameter (Name=value) followed by name (in Python3.0), followed by any name or Name=value The keyword-only parameter (in Python3.0), followed by the **name form.
In the call and function header, if the **arg form is present, it must appear at the end.

Inside Python, you use the following steps to match parameters before assigning values:

    • Assign non-keyword parameters by location.
    • Assigns a keyword parameter by matching the variable name.
    • Additional non-keywords are assigned to the *name tuple.
    • Additional keyword parameters are assigned to the **name dictionary.
    • The default value is assigned to parameters that are not assigned in the header.
    • After that, Python checks to make sure that only one value is passed in for each parameter. If this is not the case, an error will occur. When all matches are complete, Python assigns the objects passed to the parameter names to them.

>> examples of keyword parameters and default parameters
If you do not use any special matching syntax, Python will default to match the variable name from left to right by location.

def f (a,b,c): print (A,b,c) f (All-in-all)   #Prints

Keyword parameters

The keyword parameter allows for matching by variable name, not by location.

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

Default parameters

The default parameter allows you to create optional parameters for the function. If no value is passed in, the parameter is assigned the 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 of keyword parameters and default parameters

def func (spam,eggs,totast=0,ham=0): Print ((spam,eggs,totast=0,ham=0)) func     #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)

>> examples of arbitrary parameters
The last two matching extensions, * and * *, are for the function to support receiving any number of arguments.

Collect parameters

In the function definition, the mismatched positional parameters are collected in the tuple.

def f (*args):p rint (args)

When this function is called, Python collects all positional related parameters into a new tuple and assigns that tuple to the variable args. Therefore, it is a generic tuple object that can be indexed or iterated.

* * feature is similar, but it is valid only for keyword parameters. Pass these keyword arguments to a new dictionary, which will then be processed by the generic dictionary tool. In this case, * * Allows the keyword argument to be converted to a dictionary, which you can then use to make a step or dictionary iteration with a key call.

def f (A,*pargs,**kargs):p rint (A,pargs,kargs) F (1,2,3,x=1,y=2)  #Prints: 1 (2,3) {' X ': 2, ' Y ': 1}

Unpacking parameters

In the latest version of Python, we can use the * syntax when calling a function. In this case, it is contrary to the meaning of the function definition. Instead of creating a collection of parameters, it will unpack the collection of parameters.

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

Similarly, when a function is called, the * * will unpack a dictionary as a key/value pair, making it a separate keyword parameter.

Args={' A ': 1, ' B ': 2, ' C ': 3}args[' d ']=4func (**args)   #Prints 1,2,3,4

Note: Do not confuse the function header and the function call when */** syntax: In the head, it means to collect any number of arguments, and at the time of invocation, it unpack any amount of arguments.

Application function Versatility

If 
 
  
   
  : Action,args=func1, (
 1,) Else:action,args=func2, (...) action (*args)
  

>>python3.0 keyword-only Parameters
Python3.0 generalized the collation of the function header, allowing us to specify the Keyword-only parameter-the parameter that must be passed only by keyword and not populated by a positional parameter.

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

We can also use a * character in the argument list to indicate that a function does not accept a parameter list of variable lengths, but still expects all parameters followed by * 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 (all in all)  #Error!

In the preceding code, B and C must be passed by keyword, and no additional locations are allowed to pass.

In addition, the default function is still valid for the keyword-only parameter, so, in fact, the keyword-only parameter with the default value is optional, but those keyword-only parameters that do not have a default value really become the keyword-only parameter required by the function.

Collation Finally, note that the Keyword-only parameter must be specified after a single asterisk, not two asterisks--named arguments cannot appear after the **args of any keyword, and a * * cannot appear in the argument list on its own. Both of these practices will produce errors.

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

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

In fact, in function calls, similar collations are true: when passing keyword-only parameters, they must appear before a **args form. The keyword-only parameter can be written before or after *arg, and may be included in the **args:

def f (a,*b,c=6,**d):p rint (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 uses only variable names, Python creates, alters, or looks for variable names in the so-called namespace (where a variable name is stored). That is, the position in the code where the variable name is assigned determines the scope in which the variable name can be accessed, which determines which namespace it exists in.

In addition to the wrapper, the function adds an additional namespace layer to the program: By default, all variable names for a function are associated with the namespace of the function. This means that:

A variable defined within DEF can be used in code within DEF and cannot be used outside of a function to apply such variable names.
The variable name in Def does not conflict with a variable name other than Def, and a variable x that is assigned outside of DEF is an entirely different variable from the variable x that is assigned to the def.
>> Scope Rules
Before we start writing functions, all the code we write is at the top level of a module (that is, not nested in def), so the variable name we use is either in the module file itself or in Python's built-in pre-defined. The function defines the local scope, and the module defines the global scope. The two scopes have the following relationship:

The embedded module is the global scope each module is a global scope (that is, a namespace of variables created at the top level of the module file). For the outside of the module, the module's global variable becomes the property of the module object, but it can be used like a simple variable in this module.
The scope of the global scope is limited to a single file here the global refers to the variable name at the top level of a file is global only for the code inside the file. In Python there is no global scope based on a single, all-encompassing scenario file.
Each call to a function creates a new local scope
Assignment variable name is local unless declared as a global or non-local variable
All variable names can be grouped into local, global, or built-in
>> Variable name resolution: LEGB principle
Python's variable name resolution mechanism is sometimes called the LEGB rule, and Python searches for 4 scopes when using an unauthenticated variable name in a function:

    • Local scope (L)
    • Local scope (E) of def or lambda in the previous layer structure (in fact, the case of function nesting)
    • Global scope (G)
    • And finally the built-in scope (B)

Python looks for variables in the above 4 scopes sequentially, and stops at the first place where the variable name can be found, and if none of the 4 scopes are found, Python will error.

It is important to emphasize that the above four scopes are the search process for the code in the function, that is to say, the variables in the previous layer can be used directly in the function!

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

>> built-in scopes
The built-in scopes are implemented by a standard module called BUILTIN, but the variable name itself is not placed inside the built-in scope, so you must import the file to be able to use it. In Python3.0, you can use the following code to see exactly which variables are predefined:

Import Builtinsdir (Builtins)

Therefore, there are actually two ways to refer to a built-in function: The benefits of the LEGB rule, or the manual import of 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 only makes it the first place where the variable name is found to take effect!

Global statement

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

A global variable is a variable name that is located at the top level of the module file.
Global variables must be declared if they are assigned inside a function.
The global variable name can be referenced inside 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 a value or reference, all listed variable names are mapped to the scope of the entire module. As an example:

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

scopes and nested functions

This section is about the layer of E in the LEGB lookup law, which includes the local scope within any nested function. Nested scopes are sometimes called static nested scopes. In fact, nesting is a syntactically nested scope, which is a nested structure that corresponds to the physical structure of the program's source code.

>> details of nesting scopes
For a function:

A reference (x) first finds the variable name X in the local (function) scope, then the local scope in the function nested within the syntax of the code, looks inside and out, then finds 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, from the point of Reference X, a layer of online search, until the first x found.
By default, an Assignment (X=value) creates or modifies the current scope of the variable name X. If X is declared as a global variable inside 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 inside the function, the assignment modifies the name X in the local scope of the nearest nested function.
>> Nested Scope examples

x = 99def F1 (): x = F2 def (): Print (X) F2 () F1 () #Prints 88:enclosing def Local

The first thing to note is that the above code is legal, and DEF is a simple execution statement that can appear where any other statement is possible, including nesting in another def. In the code, F2 is a function defined in F1, in which case F2 is a temporary function that exists only during F1 internal execution (and is only visible to code in F1). With the LEGB lookup rule, x in F2 automatically maps to F1 x.

It is important to note that this nested scope lookup is also valid after the nested function has been returned.

x = 99def F1 (): x = F2 def (): Print (X) #Remember X in enclosing def scope return F2 #Return F2 and don ' t call itaction = F1 () #Make return functionaction () #Call it now:prints 88

In the code above, the return value is 88,F2 remembering the x in the nested scope in F1, regardless of the number of action functions called, although F1 is not already active at this time.

Factory functions

These behaviors are sometimes called closures (closure) or factory functions-a function that remembers the value of a variable in a nested scope, even though that scope may no longer exist. Generally, a better choice is to use classes to record state information, but factory functions like this provide an alternative. Specific examples are:

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,retur N 9f (4) #return 4**2g=maker (3) #g remembers 3,f remembers 2g (3) #return 27f (3) #return 9

As can be seen from the above code, the F and G functions record different n values, that is, record the different states, each time the factory function is assigned, will get a set of state information, each function has its own state information, by the maker of the variable n is maintained.

The scope is more than the default parameter with the loop variable

There is a notable exception in the given law: if a lambda or def is defined in a function, nested within a loop, and the nested function refers to a variable in the upper scope, the variable is changed by the loop, and all the functions produced in the loop will have the same value- The value of the referenced variable when completed in the last loop. Specific examples are:

Def makeactions (): acts=[] for I in range (5): #Tries to remember each i acts.append (lambda x:i * * x) #All remember same l AST It return acts

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

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

Def makeactions (): acts=[] for I in range (5): #Use default instead acts.append (Lambda x,i=i:i * * x) #Remember current I R Eturn acts{

nonlocal statements

In fact, in Python3.0, we can also modify nested scope variables as long as we declare them in a nonlocal statement. With this statement, the nested def can read and write access to the names in the nested function. Nonlocal applies to a name in the scope of a nested function, not to global module scopes other than all def--they may only exist in a nested function and cannot be created by the first assignment of a nested def.

In other words, nonlocal allows assigning a value to a name variable in a nested function scope, and restricts such a name scope lookup to a nested def.

>>nonlocal Foundation

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 within another function, the nested function can refer to the variables defined in the previous function, but cannot modify them. In Python3.0, a nested scope is declared in a nonlocal statement so that the nested function can be assigned a value, and thus the name can be modified.

In addition to allowing the names in the nested def to be modified, the nonlocal statement also accelerates the reference-just like the global statement, nonlocal causes the lookup of the names listed in the statement to start from within the scope of the nested Def, rather than starting from the local scope of the declared function, which means that Nonlocal also means "completely skipping my local scope".

In fact, when executing to the nonlocal statement, the name listed in nonlocal must be defined in advance in a nested DEF, otherwise an error will be generated. The direct effect is similar to global: global means that the name is in the previous layer of the module, nonlocal means that they are in a previous level def function. Nonlocal is even stricter-scope lookup is limited to nested def. In other words, nonlocal can only appear in nested Def, not in the global scope of the module or in a built-in scope outside of def.

When used in a function, both the global and nonlocal statements limit the lookup rule to a certain extent:

Global enables scope lookups to begin with the scope of the nested module and allows assigning a value to the name there. If the name does not exist with the module, the scope lookup continues to the built-in scope, but the assignment of the global name is always created or modified in the scope of the module.
Nonlocal limit scopes lookups are only nested DEF, requiring names to already exist there, and allowing them to be assigned values. Scope lookups do not continue to global or built-in scopes.
>>nonlocal applications
Use nonlocal to modify

DEF tester (start): state = start #each call gets it own State def nested (label): nonlocal state #remember State in Enclos ing scope print (label,state) state+=1 #Allowed to change it if onolocal return NESTEDF = Tester (0) #Increments state on EA Ch callf (' spam ') #Prints: spam 0F (' Ham ') #Prints: Ham 1F (' eggs ') #Prints: Eggs 2

Boundary conditions

When executing a nonlocal statement, the nonlocal name must already be assigned in a nested DEF scope, or an error will be obtained.
Nonlocal limit scopes Lookup only for nested def,nonlocal does not look in the nested module's global scope or in a built-in scope other than all def.

  • 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.