Welcome to the column [the strongest in the whole network] Python system learning manual
catalogue
3, Local function (nesting of functions)
4, Advanced content of functions
1, Introduction to functions
1. Concept
 Functions are code fragments that can repeatedly perform certain tasks, with independent fixed input and output interfaces.
 The essence of function definition is to give a piece of code a name for easy reuse in the future
 In order to facilitate calling this function later, when defining it, it is necessary to specify its input (parameters) and output (return value).
2. Define the syntax format of the function
def Function name(parameter list ): #Executable statement return Return value
Function name
 As long as it is a legal identifier (the same as variable naming)
 To improve readability, it is recommended that the function name be composed of one or more meaningful words, underlined between words_ Separate, all lowercase letters
parameter list
 In the parentheses after the function name, multiple formal parameters are separated by commas, and there can be no parameters
 Parameters can have default values. You can directly specify the default value with the equal sign =. Parameters with default values must rank last
 Parameters without default values must be specified when calling
 Formal parameters can also be absent, but parentheses cannot be omitted
 Specify a name when calling a parameter with a default value
Return value
 The return value can be zero, and the sentence return is omitted directly
 The return value can be one or more, separated by commas and combined into a tuple
 The return value can also be an expression
 Multiple return values. Replace unnecessary ones with underscores!
3. Function documentation (comment → help)
 An annotated text explains the function.
 You can use help() to view the documentation of the function. As long as you put a string immediately after the declaration line of the function, it can be recognized by help.
4. Examples
# Function definition def myfunc(arg1, arg2, arg3=None): ''' This is a example for python documentation. This is a python Function provides an example of a document. arg1: Description of the first parameter arg2: Description of the second parameter arg3: Description of the third parameter (this parameter has a default value) v1, v2, v3: Description of the return value ''' v1 = arg1 + arg2 v2 = arg1 * arg2 if arg3 is None: v3 = arg1 + arg2 else: v3 = arg1 + arg2 + arg3 return v1, v2, v3 # function call v1, v2, v3 = myfunc(5, 3, arg3=4) print(v1, v2, v3) #8 15 12 # Call the function with the default value of arg3 v1, v2, v3 = myfunc(5, 3) print(v1, v2, v3) #8 15 8 # Ignore a return value v1, v2, _ = myfunc(5, 3) print(v1, v2, v3) #8 15 8 # The returned value is tuple, which is automatically unpacked during the return process print(type(myfunc(5,3))) #<class 'tuple'>
2, Parameters of function
 The parameters of a function are the channels through which the parameters interact with external variable inputs.
 The parameter name of the function shall meet the identifier naming specification and have clear meaning. The meaning of each parameter can be known through the parameter name.
 Note the meaning of the function (and return value) one by one in the comments below the function definition, so that users can use it correctly even if they don't know the specific contents of the function.
 Argument: actual parameter, the actual parameter passed from outside
 Formal parameter: formal parameter, its formal name inside the function
 When a function is called, the argument is bound to the formal parameter according to the sequence position, which is called the Positional Argument
 You can also specify the corresponding relationship between the actual participating formal parameters during the call, which is called Keyword Argument. At this time, the location information is ignored
 When passing location parameters and keyword parameters at the same time, you should pass location parameters first and then keyword parameters!
 When defining a function, you can specify a default value, but the parameters with default values must be listed at the end of the parameter list
#Take a small chestnut and calculate the volume of the paper box def cube_volume(length, width, height = 0.25): ''' Calculate the volume of the paper box(Company: m) length: Long; width: wide height: High (default parameter 0).25) v: Return value, carton volume, unit m**3 ''' if length <= 0: print('length must larger than 0!') return 0 if width <= 0: print('width must larger than 0!') return 0 if height <= 0: print('height must larger than 0!') return 0 v = length*width*height print('length = %.2f; width = %.2f; height = %.2f; cube volume = %.2f' % \ (length, width, height, v)) return v # Call with positional parameters v = cube_volume(1, 2, 3) # Call with keyword parameters v = cube_volume(width = 1, height = 2, length = 3) # Mixed use of location parameters and keyword parameters v = cube_volume(1, height = 2, width = 3) # The keyword parameter will report an error before the location parameter # v = cube_volume(width = 1, 2, 3)
1. Variable object
 If the parameter is a variable object (such as a list), the modification of this object within the function will still be valid after the function is executed
 If the default parameter is a variable object, the default value of the function changes after the object is modified inside the function!
 The actual function passes in the address. The function body will not pass out the address, but the value corresponding to the address has changed.
# Power operation on list def pow_list(x, p): ''' power of a list x: list p: power not return value ''' for i in range(len(x)): x[i] **= p #This will output the value after power, but will not change the value in the x list #Because the value in x is passed into a new parameter for calculation #for i in x: # i **= p # print(i) #print(x) x = [1,2,3,5,7,9,10,12] pow_list(x,2) print(x) # It can be seen that the internal changes of the function to the elements in the list x are still valid after the function exits
Using the characteristics of variable objects, a hidden parameter recorder can be made ðŸ‘‡
# Hidden parameter recorder def growing_list(x, y=[]): y.append(x) print(y) # What happens when the growing_list('a ') is executed repeatedly? growing_list(2) #[2] growing_list('Zhang San') #[2, 'Zhang San'] growing_list(22333) #[2, 'Zhang San', 22333]
2. Parameter collection (variable number of parameters)
 Parameter collection specifies that an indefinite number of parameters can be passed to the function, for example, sometimes 3, sometimes 5, sometimes 10, and so on.
 When passing an indefinite number of parameters, an asterisk "*" shall be added when defining the parameters (tuple with empty formal parameters).
 Parameters with an asterisk can be anywhere in the parameter list (not necessarily the beginning or the end). python requires that a function can only have one parameter with an asterisk.
# Summation of indefinite numbers def my_sum(*t): # Input parameters with asterisks are treated as tuples print(t, type(t)) sum = 0 for s in t: sum += s return sum # In fact, the function accepts an indefinite number of input parameters my_sum(1,2,3,4,2233)

If there are other parameters after the star parameter, they must be passed in the form of keyword parameters, otherwise python will collect them into the star parameter if it doesn't know what they are.
# Sum after multiplication of indefinite numbers def pow_sum(*t, p): # Input parameters with asterisks are treated as tuples print(t, type(t)) sum = 0 for s in t: sum += s**p return sum # For the last parameter p, you need to specify keyword transfer pow_sum(1,2,3,4,2233,p=2) # If the keyword is not specified, an error will be reported # pow_sum(1,2,3,4,2233,2)
3. Solve a practical problem
# Numerical weighted summation of indefinite numbers # The weight changes with the number of numbers def weighted_sum(x1,x2,*y): sum = 0 n = len(y) weight = 1/3/n for i in y: sum += weight*i return sum+1/3*x1+1/3*x2 weighted_sum(1,2,3) weighted_sum(1,2,3,22,44,55) weighted_sum(1,2,3,4,5,6)
4. Parameter collection (collect keyword parameters)
 python supports parameters with two asterisks in addition to parameters with one model. Its function is to collect keyword parameters.
 A function can take at most one star parameter (collection location parameter) and one two star parameter (collection keyword parameter).
 The binary parameter exists in the form of a dictionary inside the function.
 The twostar parameter must be at the end of the parameter list. There can be no other keyword parameters and location parameters after it.
# Test one satellite parameters and two satellite parameters def test_star(a, b, c, *onestar, **twostar): print('a = %d; b = %d; c = %d' % (a, b, c)) print(onestar, type(onestar)) print(twostar, type(twostar)) test_star(1, 2, 3, 4, 5, 6, s1 = 7, s2 = 8, s3 = 9) # In another order? # test_star(1, 2, 3, 4, 5, 6, s1 = 7, s2 = 8, s3 = 9, a = 10, b = 11, c = 12) # An error is reported. No keyword parameters can be passed after the twostar parameters (of course, neither can the location parameters)
 The "parameter collection" function will collect as few parameters with stars as possible and leave more parameters to normal location parameters and keyword parameters
# If there are default parameters, pay attention to possible bug s def test_star(a, b, c, p = 5, *onestar, **twostar): print('a = %d; b = %d; c = %d; p = %d' % (a, b, c, p)) #a = 1; b = 2; c = 3; p = 4 print(onestar, type(onestar)) #(5, 6) <class 'tuple'> print(twostar, type(twostar)) #{'s1': 7, 's2': 8, 's3': 9} <class 'dict'> # Will pass a p=4 in instead of the assumption, onestar=(4,5,6) test_star(1, 2, 3, 4, 5, 6, s1 = 7, s2 = 8, s3 = 9)
5. Reverse parameter collection (explosion parameter)
 Lists, tuples, dictionaries, etc. defined outside the parameters can be "exploded" when transmitting parameters, and the contents are automatically allocated to the parameter list
 To "explode" a list or tuple, you need to add an asterisk in front of it.
 "Bomb" dictionary needs to be preceded by two asterisks.
# Explosion parameter example def zha(a,b,c): print(a,b,c) # Fried tuple z = (1,2,3) #1 2 3 zha(*z) # Fried list z = [4,5,6] #4 5 6 zha(*z) # Fried dictionary z = {'a':7,'b':8,'c':9} #7 8 9 zha(**z) # Fried dictionary z = {'c':7,'a':8,'b':9} #8 9 7 zha(**z) # If the number of parameters or keys after explosion do not match, an error will be reported # z = {'c':7,'a':8} # zha(**z)
6. Memory management of parameters
 python parameter passing, passing the parameter value rather than the parameter address. The parameter value is copied and passed to the progressive function.
 For numeric parameters (integer, floating point, complex number, etc.), changing the parameter value inside the function is not affected outside the function.
 For container type parameters (list, dictionary, string, etc.), the contents of the container are changed in the function, which can also be reflected outside the function.
# Pass numeric type parameters # Modification within the function is not affected outside the function def mod_para1(a,b): print('In mod_para1, before modification: a = %d; b = %d' % (a,b)) #a = 2; b = 8 a *= 2 b += 4 print('In mod_para1, after modification: a = %d; b = %d' % (a,b)) #a = 4; b = 12 a = 2 b = 8 print('Out of mod_para1, before modification: a = %d; b = %d' % (a,b)) #a = 2; b = 8 mod_para1(a,b) print('Out of mod_para1, after modification: a = %d; b = %d' % (a,b)) #a = 2; b = 8
 Pass container type parameters
 Modification inside the function can also be reflected outside the function, and this method can also be used to transfer information to the outside world
 If you do not want the contents of the container type to be modified, use the copy.copy() copy.deepcopy() method manually
# When the list passes parameters through the function, the data is changed def mod_para2(x): print('In mod_para2, before modification: x = ' + str(x)) for i in range(len(x)): x[i] *= 2 print('In mod_para2, after modification: x = ' + str(x)) x = [i for i in range(10)] print('Out of mod_para2, before modification: x = ' + str(x)) mod_para2(x) print('Out of mod_para2, after modification: x = ' + str(x)) import copy A = [1,2,3]; B = copy.copy(A) mod_para2(B); print(A,B)
7. Scope of variable in function
 Created outside the function, it is Global and visible anywhere inside this py file.
 It is created inside the function. It is Local. It can only be accessed inside the function and not visible outside the function.
 Global variables and local variables have the same name. Local variables will be accessed inside the function and global variables will be accessed outside the function.
 Function can access global variables, but cannot be modified!
 If you have to modify a global variable inside a function, you need to declare it (this is not recommended!)
gv1 = 1 def test(): # gv1=2 print('To access global variables inside a function: gv1 = %d' % gv1) #1 # gv1=2 test() print('To access global variables outside a function: gv1 = %d' % gv1) #1
 In the above example, an error will be reported in the previous line of gv1 = 2. It looks incredible.
 In fact, this is Python's "hide" operation on global variables. When assigning a value to a nonexistent variable inside a python function, the local variable will be redefined by default. In other words, gv1 is redefined inside the whole function. This operation will affect the whole function, so an error will be reported on its previous line.
 In order to access the masked global variables, you need to use the globals() function to output the global variables in the form of a dictionary. (globals() ['global variable name']  or you can simply think that global variables are stored through the dictionary in globals()
 At present, we know that there will be no error after Python 3.10, but this operation method is generally not recommended!
# Accessing masked global variables gv1 = 1 def test(): # Use the globals function to access the masked global variables print('To access global variables inside a function: gv1 = %d' % globals()['gv1']) gv1 = 2 print('Access the modified global variable inside the function: gv1 = %d' % gv1) test() print('To access global variables outside a function: gv1 = %d' % gv1) # The internal modification of the function is actually a local variable with the same name, and the global variable has not been modified.
 Normal practice is that as long as a global variable is defined, the local variable inside the function should not have the same name as it!
 Global statements can be used to declare global variables inside the function, and the declared global variables can be accessed and modified inside the function.
# Test global variables gv1 = 1 def test(): global gv1 #I'll control the global variables print('To access global variables inside a function: gv1 = %d' % gv1) #1 gv1+=1 test() print('To access global variables outside a function: gv1 = %d' % gv1) #2
8. Get variables within the specified range
 python provides several methods that allow us to access the "name" of each variable and the "value" they hold
 Variables store "name" and "value" pairs somewhere in memory
 Globals(): returns the dictionary composed of all variables in the global scope, globals() ["name"]
 locals(): returns a dictionary consisting of all variables in the current function range
 vars(object): get the dictionary composed of all variables within the specified object range (if the object parameter is not passed in, the functions of vars and locals are exactly the same)
 If locals() is called in the global scope (outside the function), it behaves like globals(), and lists all variables in the global scope
 Generally speaking, the variable dictionaries listed in the above functions should not be modified! But in fact, they can be modified!! Modifying variables in this way is not recommended.
3, Local function (nesting of functions)
 python can define functions inside functions, and multiple functions are nested with each other. Functions inside other functions are called "local functions".
 Local functions are hidden from the outside and can only be used inside the function that defines them.
 python functions can also be used as return values. If local functions are used as return values, they can be used in other functions.
One chestnut (switching of multiple average values using local functions)
# The switching of multiple average values is realized by using local functions def mymean(x, mtype = 'arithmetic'): '''Calculation list x Average of, in mtype Defines which average value to calculate. The default value is arithmetic average( arithmetic mean) ''' def arithmetic(x): ''' Arithmetic mean( arithmetic mean) ''' m = sum(x)/len(x); return m def geometric(x): '''Geometric mean( geometric mean) ''' p = 1.; n = len(x) for i in range(n): p *= x[i] m = p ** (1/n); return m def harmonic(x): ''' Harmonic mean( harmonic mean) ''' s = 0.; n = len(x) for i in range(n): s += 1/x[i] m = 1/(s/n); return m if mtype == 'arithmetic': return arithmetic elif mtype == 'geometric': return geometric elif mtype == 'harmonic': return harmonic else: return arithmetic
 Similar to the local variable masking the global variable in a function, the variable in a local function will also mask the local variable of its function.
 Therefore, when using local functions, we should also pay attention to the problem of variable names. The variable names of functions at different levels should be different.
 If you want to access the local variables of the previous function, you should declare them with nonlocal in the local function (similar to declaring global variables with global).
# If the variables in the local function conflict with the local variables in the function, this program will report an error def test1(): fv = 1 def test2(): # print('Print the local variables in the upper function within the local function:%d' % fv) # Will report an error here fv = 2 print('Print the local variables in the upper function within the local function (after change):%d' % fv) #2 test2() print('Print local variables in the upper function (after change):%d' % fv) #1 return fv print('Print local variables outside the upper function (after change):%d' % test1()) #1
Global variables can be used / changed using the nolocal declaration
# The variable in the local function conflicts with the local variable in the function. It should be changed so that no error is reported def test1(): fv = 1 def test2(): nonlocal fv # Use nonlocal declaration to declare fv as the variable of the upper function print('Print the local variables in the upper function within the local function:%d' % fv) #1 fv = 2 print('Print the local variables in the upper function within the local function (after change):%d' % fv) #2 test2() print('Print local variables in the upper function (after change):%d' % fv) #2 return fv print('Print local variables outside the upper function (after change):%d' % test1()) #2
4, Advanced content of functions
 Everything in python is an object, and a function is also an object. A function can be assigned to a variable, as a parameter of a function, or as a return value of a function.
 The use of function as object in python can be compared with function pointer in c language, but it is much more flexible and less error prone than function pointer.
# Take the mymean function in chestnut in Chapter 3 as an example # Assign function to variable f f = mymean2('arithmetic') # Print it out print(f) # Test it x = list(range(1,10)) m = f(x) print(m) # You can also write it together like the example above print(mymean2('geometric')(x))
1. Function as formal parameter of function
 Sometimes it is necessary to define a function to fix the general internal process, but some parts can be replaced: similar to changing the engine for a car and changing the graphics card for a computer.
 This "replaceable" programming method can be easily realized in python by taking functions as formal parameters.
2. Use function as return value
 Taking a function object (which can be a local function or a function defined elsewhere) as the return value is suitable for judging which part to use in "part replacement" programming.
 See the code in the local variable chestnut in Chapter 3 for the specific implementation
# Take the mymean function in chestnut in Chapter 3 as an example # Write another program to transform the numbers in the list into another list with an average of 1 # Mean value can be arithmetic mean value, geometric mean value and harmonic mean value def mynormalize(x, mtype): f = mymean(mtype) m = f(x) return [i/m for i in x] x = list(range(1,10)) mtype = 'geometric' print(mymean(mtype)(x)) print(mynormalize(x, mtype))
3. Recursion
 Calling itself in a function is called recursion.
 Recursion can be regarded as an implicit loop, which can execute a piece of code repeatedly without loop statement control.
 Recursion is very useful in large and complex programs, and can be used in both numerical and non numerical algorithms!
 When using recursion, it should be noted that when a function calls itself continuously, it must ensure that the return value of the function is determined at a certain time, that is, it will not call itself again.
# Fibonacci sequence # Fibonacci sequence has direct applications in modern physics, quasicrystal structure, chemistry and other fields def Fibonacci(n): ''' Fibonacci sequence f(0)=1, f(1) = 1, f(n) = f(n1)+f(n2) ''' if n == 0 or n == 1: return 1 else: return Fibonacci(n1) + Fibonacci(n2) # Test it. Note that n should not be set too large. The recursive efficiency of python is relatively low and it will crash too often print(Fibonacci(5)) # Fibonacci series, top 20 print('Fibonacci sequence:') for i in range(20): print('%d: %d' % (i,Fibonacci(i)))
5, Local functions and lambda
 lambda expression is a function implementation method introduced by modern programming language. It can replace local functions to a certain extent.
 For a local function, its name is only meaningful inside the function, and its name cannot be seen outside the function. Even if it is passed in the form of return value, its name is not passed at the same time.
 In the sense of naming, local functions are "anonymous". No one knows the name of this function.
 lambda expressions are equivalent to anonymous functions.
# hello world in one line greeting = lambda: print('Hello lambda!') greeting() # lambda expressions can be placed in arrays and run in batches L = [lambda x: x**2, lambda x: x**3, lambda x: x**4] for p in L: print(p(3))
1. Replace local functions with lambda expressions
# Replacing local functions with lambda expressions def mymean2(mtype = 'arithmetic'): ''' Returns the function used to calculate the average, using mtype Defines which average value to calculate. The default value is arithmetic average( arithmetic mean) ''' # Since the lambda expression can only write one line, it is implemented with the readymade functions of numpy and scipy import numpy as np import scipy.stats as st a = np.array(x) if mtype == 'arithmetic': # arithmetic mean return lambda a: np.mean(a) elif mtype == 'geometric':# geometric mean return lambda a: st.gmean(a) elif mtype == 'harmonic': # harmonic mean return lambda a: st.hmean(a) else: # Default: arithmetic mean return lambda a: np.mean(a) x = list(range(1,10)) print(x) print(mymean2('arithmetic')(x)) print(mymean2('geometric')(x)) print(mymean2('harmonic')(x))
2. Internal functions of common mathematical methods
# Judge whether all elements are True, which is equivalent to multiple and help(all) print(all([3>2,6<9])) # Whether any element is True is equivalent to multiple or help(any) print(any([3>2,6<9])) # Maximum and minimum help(max) help(min) print(max([1,2,5,3])) print(min([1,2,5,3])) # Rounding (to the nth place after the decimal point) help(round) print(round(3.1415926,3)) # Add all elements help(sum) print(sum([1,2,3])) print(sum([1,2,3],5)) # Power help(pow) print(pow(6,2)) print(pow(6,2,5)) # Division with remainder help(divmod) print(divmod(6,2)) # absolute value help(abs) print(abs(2.56))
This is the end of the detailed explanation of this issue. I hope it will be helpful to you. Thank you for watching!
I will continue to update the relevant knowledge of programming and learning. Welcome to pay attention to my blog. Your praise and attention are the driving force for me to continue to share.
Welcome to the column [the strongest in the whole network] Python system learning manual , if you have any questions, you can comment or communicate by private letter. Thank you!