SoFunction
Updated on 2024-11-16

Python Full Stack Scopes and Closures

1. return return value

### return The return value of a custom function.
"""
Concept: return returns the data inside the function to the outside of the function, to the caller of the function.
 + The six standard data types, in addition to the function or class object can be returned.
 When executed, it means that the function is terminated and the code that follows is not executed.
3. If you do not define the return value, the default return value is None.
"""
# (1) return + six standard data types
def func():
	# return 111
	# return 6.89
	# Return "You're so handsome, I love you" #
	# return [1,2,3]
	# return {"a":1,"b":2}
	return 1,2,3 # Return tuple
res = func()
print(res)
# (2) return, when executed, means that the function is terminated and the following code is not executed.
def func():
	print(1)
	print(2)
	return 3
	print(4)
res = func()
print(res)
def func():
	for i in range(5):
		if i == 3:
			return 4
		print(i)
res = func()
print(res)
# (3) If return is not defined, it returns None by default.
def func():
	pass
res = func()
print(res) # None
# Note that the data printed and the data returned are not equivalent, the data returned is customizable.
res = print(1234)
print(res)  # None

# Analog +-*/Calculator
"""
Function: Completes the calculation
Parameters: 2 numbers and operator
Return Value: The result of the calculation
"""
def calc(num1,num2,sign):
	if sign == "+":
		return num1 + num2
	elif sign == "-":
		return num1 - num2
	elif sign == "*":
		return num1 * num2
	elif sign == "/":
		if num2 == 0:
			return "The divisor cannot be zero."
		return num1 / num2
	else:
		return "I'm sorry, it's out of my range."
res = calc(3,5,"+")
res = calc(3,5,"-")
res = calc(3,5,"*")
res = calc(3,0,"/")
res = calc(3,0,"&")
print(res)

2. global_local_variables

### Global and Local Variables
"""
1.conceptual
	local variable:在函数内部定义的变量就是local variable
	global variable:Variables defined outside of a function or inside a function using theglobal关键字声明是global variable
2.scope (computing):
	local variable的作用范围仅仅在函数的内部
	global variable的作用范围横跨整个文件
3.life cycle:The duration of the variable
	built-in namespace -> global namespace  -> local namespace (Order of opening space)
	built-in property > Global Properties > local property (duration of action:elder->shortness)
"""
# 1 Local variables
def func():
	# Define a local variable
	a = 1
	# Get the current local variable
	print(a)
	# Modify a local variable
	a = 2
	print(a)
func()
# print(a) error
# 2. Global variables
# Define a global variable
b = 10
# Get the current global variable
print(b)
# Modify a global variable
b = 20
print(b)
def func():
	print(b)
func()
# 3. Defining global variables inside a function
def func():
	global c
	c =30
func()
print(c)
# 4. Modifying global variables inside a function
d = 50
def func():
	global d
	d = 51
func()
print(d)
"""
Summarizing: the use of global
If a global variable does not currently exist, you can define it within a function using the global keyword.
If a global variable exists, you can modify it within a function using the global keyword.
"""

3. Use of function names

### Use of function names
"""
# Functions in python can be dynamically created and destroyed like variables, passed as arguments, and returned as values, called first class objects. Other languages have limited functionality
"""
def func():
	print( "I am the func function.")
# (1) Dynamically created
a = 1
print(a)
a = func
a()
# (2) Dynamic destruction
del a
# a()
# func()
# (3) When the parameter is passed
def func2():
	return "I am the func2 function."
def func1(f):
	return f() # "I am the func2 function" #
res = func1(func2)
print(res)
# (4) returned as a value
def func3():
	print( "I am the func3 function." )
def func4(f):
	return f
res = func4(func3)	
print(res)
res()
print("<===>")
# (5) Function names can be elements of container type data
lst = [func,func3]
for i in lst:
	i()
print("<=========>")
# ### __doc__ or help to view the documentation.
def big_chang_cishen(something):
	"""
Function: Teach you how to eat large intestine
Parameters: What to eat
Return Value: Satisfaction
"""
	print("particle marking the following noun as a direct object{}Let's have a wash.".format(something))
	print("Take the head of the intestine, put it in your mouth and suck on it.")
	print("Wipe your mouth and put down your gut with satisfaction.")
	return "It's finished. It's delicious."
big_chang_cishen("Raw intestines.")
# Method I
res = big_chang_cishen.__doc__
print(res)
# Method II
help(big_chang_cishen)

4. Nesting of functions

4.1 Nesting of functions

### Nesting of functions
"""
Two functions nested within each other![Please add a picture description](/?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA54as5aSc5rOh5p645p2e,size_20,color_FFFFFF,t_70,g_se,x_16)
:
	The outer layer is called the outer function,The inner layer is the inner function
"""
def outer():
	# inner()
	def inner():
		print("I am the inner function.")
""""""
# (1) Can an internal function be called directly from outside the function? No.
# inner()
# (2) After calling an external function, can the internal function be called from outside the function?
# outer()
# inner()
# (3) Can an internal function be called from within a function? - Yes.
outer()
# (4) Is there an order of precedence when internal functions are called within a function?
# Define first before calling
# In other languages there are preloading mechanisms, where functions are resident in memory in advance, and then the script content is compiled.
# python doesn't have a mechanism for preloading functions, you have to define them before you call them; # python doesn't have a mechanism for preloading functions, you have to define them before you call them.

# The outer function is outer the middle function is inner the inner function is smaller ,call smaller function
def outer():
	def inner():
		def smaller():
			print("I am the smaller function.")
		smaller()
	inner()
outer()

# LEGB Principles
def outer():	
	def inner():
		def smaller():	
			print(a)
		smaller()
	inner()
outer()
"""
LEGBformula(就近找变量formula)
# The order of calls to find variables uses the LEGB principle (i.e., proximity principle)
B —— Builtin(Python);PythonNamespaces for built-in modules      (built-in scope)
G —— Global(module); Namespace outside the function        (global scope)
E —— Enclosing function locals;Scope of externally nested functions(nested scope (computing))
L —— Local(function);Scope within the current function            (local scope)
依据就近formula,bottom top inside out search in sequence
"""



4.2 Use of nonlocal

### Use of nonlocal (for modifying local variables)
"""
nonlocalcomply withLEGBformula
(1) It will look for variables in the previous level of the current space to modify
(2) If the upper floor space is not,Keep looking up.
(3) If you can't find it in the end,Direct Error
"""
# (1) It will look for variables in the previous level of the current space to be modified
def outer():
	a = 10
	def inner():
		nonlocal a
		a = 20
		print(a)
	inner()
	print(a)
outer()
# (2) If there's no space on the previous level, keep looking upward
def outer():
	a = 20
	def inner():
		a = 15
		def smaller():
			nonlocal a
			a = 30
			print(a)
		smaller()
		print(a)
	inner()
	print(a)
outer()
# (3) If you can't find it at the end, just report an error.
"""nonlocal can only modify local variables,"""
"""
a = 20
def outer():	
	def inner():
		def smaller():
			nonlocal a
			a = 30
			print(a)
		smaller()
		print(a)
	inner()
	print(a)
outer()
error
"""

# (4) Is it possible to modify local variables without nonlocal? ok
def outer():
	lst = [1,2,3]
	def inner():
		lst[-1] = 3000
	inner()
	print(lst)
outer()

5. Definition of closed functions

### Closed functions
"""
If two functions are nested within each other, if the inner function uses local variables of the outer function
and the outer function returns the inner function, it is called a closure.
The inner function is called a closure.
Is it a closure?
1. The inner function uses the local variables of the outer function.
2. The outer function returns the inner function
"""
# 1. Basic grammatical forms
def zhaoshenyang_family():
	father = "Ma Yun"
	def hobby():
		print("I don't have an ounce of interest in money.,I don't value money.,This is my dad.{}said".format(father))
	return hobby
func = zhaoshenyang_family()
func()
print("<==1==>")
tup = func.__closure__
print(tup[0].cell_contents) # Ma Yun
print(tup)
print("<==2==>")
# 2. Complex forms of closures
def zhaowanli_family():
	gege = "Wang Si Cong"
	didi = "The King of Shoes, Gao Zhenning."
	money = 1000
	def gege_hobby():
		nonlocal money
		money -= 500
		print("I don't care if he's rich or not.,Not as rich as me, anyway..I like to have girlfriends.... There's still money left.{}".format(money))
	def didi_hobby():
		nonlocal money
		money -= 400
		print("Shoeboxes in the house,All kinds of luxury shoes,A pair of probably20~30ten thousand,There's still money left.{}".format(money))
	def big_master():
		return [gege_hobby,didi_hobby]
	return big_master
func = zhaowanli_family()
print(func)
lst = func()
print(lst)
# Get brother function
gege = lst[0]
gege()
# Get the brother function
didi = lst[1]
didi()
# 3. Judging closures with __closure__ , cell_contents
"""If there is data in the returned tuple that indicates a closure, print whoever's lifecycle has been extended."""
tup = func.__closure__
print(tup)
# Get the first cell first cell_contents get the contents of the object
func1 = tup[0].cell_contents
print("<11111>")
"""Print the attributes of the closure function didi_hobby whose life cycle has been extended."""
print(func1.__closure__[0].cell_contents)
func1()
# in get second cell cell_contents get content in object
func2 = tup[1].cell_contents
print("<22222>")
"""Print the attributes of the closure function gege_hobby whose life cycle has been extended."""
print(func2.__closure__[0].cell_contents)
func2()



6. Characteristics_significance of closure

### Closures feature
"""
Features: In a closure, the inner function uses a local variable of the outer function, which is bound to the inner function, extending the lifetime of the variable.
The variable is bound to the inner function, extending the variable's lifespan
The variable is bound to the inner function, extending the life cycle of the variable to the end of the script execution.
"""
def outer(val):
	def inner(num):
		return val + num
	return inner
func = outer(10)
res = func(15)
print(res)

# ### The meaning of closures
"""Global variables have large scopes and are easily tampered with."""
num = 0
def click_num():
	global num
	num += 1 # num = num + 1
	print(num)
click_num()
click_num()
click_num()
num = 100
click_num()
click_num()
# Modified, with closures #
"""
Significance of closures.
A closure gives preference to variables in the outer function and protects the value of the closure by encapsulating it. It is not accessible from the outside.
"""
def outer():
	x = 0
	def click_num():
		nonlocal x
		x += 1
		print(x)
	return click_num
click_num = outer()
click_num()
click_num()
click_num()
x = 100
click_num()
click_num()

Tip:

def outer():
      a = 10
      def inner():
            a = 20
            print(a)
       inner()
       print(a)
outer()
The output here is20 10,The two in the nestedaVariables do not interfere with each other

Lists can be passed values directly inside and outside functions.,Modify List
There is no need to use thenolocalto modify the value of a variable。
Closures can extend the cycle of local variables  
There's no way to modify a global variable from within a function.,It must be passed through aglobal(marry sb. (of woman)nonlocalreasonable)

7. Mini-exercises

# 1. Define the function: take any parameter and print the minimum value of it.
def func(*args):
	lst = []
	for i in args:
		if isinstance(i , (float,int)):
			(i)
	print(lst)
	return lst[0]
res = func(-100,1,2,423,"sdf")
print(res)
# 2. Define the function: pass a parameter n and return the factorial of n (5! = 5*4*3*2*1)
def func(n):
	total = 1
	for i in range(n,0,-1):
		total *= i
	return total
print(func(5))
# 3. Write a function that passes in multiple real parameters (all iterable objects such as strings, lists, tuples, sets, etc.).
# # Add each element of the container in turn to the new list return
#Example: Pass in a function with two arguments [1,2,3] (22,33) and the final args will be (1,2,3,22,33).
# Method I
def func(*args):
	lst =[]
	for i in args:
		for j in i:
			(j)
	return lst
res = func([1,2,3],(5,6,7),"abc")
print(res)
# Method II
def func(*args):
	return list(args)
res = func(*[1,2,3],*(5,6,7),*"abc")
print(res)

# 4. Write function, the user passes in the name of the file to be modified, with the content to be modified, execute the function, modify the operation
# Method I
def func(filename,str1,str2):
	with open(filename,mode="r+",encoding="utf-8") as fp:
		strvar = ()
		print(strvar)
		res = (str1,str2)
	with open(filename,mode="w+",encoding="utf-8") as fp:
		(res)
func("","built-in function","plug-in (computing)")
# Method II
def func(filename,str1,str2):
	with open(filename,mode="r+",encoding="utf-8") as fp:
		strvar = ()
		res = (str1,str2)
		# print(())
		(0)
		# Clear
		()
		(res)
func("","plug-in (computing)","built-in function")

# 5. Write a function that counts the number of [numbers], [letters], [spaces], and [others] in an incoming string.
# Method I
def func(strvar):
	dic = {"num":0,"word":0,"space":0,"other":0}
	for i in strvar:
		if ():
			dic["num"] += 1 # dic["num"] = dic["num"] + 1
		elif ().isalpha():
			dic["word"] += 1
		elif ():
			dic["space"] += 1
		else:
			dic["other"] += 1
	return dic

# strvar = input("Please enter a string")
# print(func(strvar))
"""
print("You.".isalpha())
# Chinese => False
print("You.".encode().isalpha())
# Letters => True
print("a".encode().isalpha())
"""
# Method II
def func(strvar):
	dic = {"num":0,"word":0,"space":0,"other":0}
	lst = []
	for i in range(97,123):
		(chr(i))
		(chr(i-32))
	for i in strvar:
		if i in "0123456789":
			dic["num"] += 1
		elif i in lst:
			dic["word"] += 1
		elif i == " ":
			dic["space"] += 1
		else :
			dic["other"] += 1
	return dic
# strvar = input("Please enter a string")
# print(func(strvar))
# 6. Write a function that checks the length of each value in the dictionary, and if it is greater than 2, then only the first two lengths are retained, and returns the processed result.
	# Example: with parameters: dic = {"k1": "v1v1", "k2": [11,22,33,44]}
def func(dic):
	if isinstance(dic,dict):
		for k,v in ():
			print(k,v)
			dic[k] = v[:2]
		return dic
	else:
		return "Not a dictionary."
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
print(func(dic))
print(func([1,23,42,34,23,4234]))

# 7 Pass in multiple container types and count all the elements.
def func(*args):
	total = 0 
	for i in args:
		print(i)
		total += len(i)
	return total
res = func("123",[5,6,7],("Hello.","123423"))
print(res)
# Altered, not to judge the length of the string itself #
def func(*args):
	total = 0 
	for i in args:
		print(i)
		if isinstance(i,str):
			total += 1
		elif isinstance(i,(tuple,list,set,dict)):
			total += len(i)
	return total
res = func("123",[5,6,7],("Hello.","123423"))
print(res)

summarize

That's all for this post, I hope it was helpful and I hope you'll check back for more from me!