目錄
一、python的閉包
示例1:閉包
示例2:形成閉包的條件
示例3:After the closure is formed,Closure functions will get a non-null__closure__屬性
示例4:The difference between assigning a reference to a closure and calling an outer function directly
二、裝飾器
示例1:統計函數執行時間
示例2:Write a decorator that counts the runtime of a function
示例3:什麼是裝飾器
示例4:用Decorator implements permission control
示例5:保留元數據
示例6:用類實現裝飾器
示例7:裝飾類
def outer(x):
a = 300
def inner():
print(f"兩數之和{x + a}")
return inner
d = outer(10)
d()
Principles of variable resolution:
LEGB 原則
local當前局部變量 enclosing function 閉包空間 global全局 buildins 內建模塊
理論上來說,After the function is executed,變量a會釋放
But this time there isinnerfunction is referencing them,At this point, a closure is formed
Form a closure condition:(缺一不可)
1、必須有一個內嵌函數
2、內函數必須引用外函數的變量
3、外函數必須返回內函數
def outer(x):
a = 300
def inner():
print(f"兩數之和{x + a}")
return inner
d = outer(10)
d()
# After the closure is formed,Closure functions will get a non-null__closure__屬性
print(dir(d))
print(d.__closure__)
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-29-閉包和裝飾器/01、閉包.py
兩數之和310
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
(<cell at 0x0000015CD0A9FE80: int object at 0x0000015CD09993B0>, <cell at 0x0000015CD09417F0: int object at 0x0000015CBEE46A50>)
Process finished with exit code 0
雖然代碼一樣,But every time the outer function is called it will be re-executed,創建一個新的tmp_list和inner
匿名變量,All are placed in an anonymous space,所以地址一樣
tmp_list = []
def outer():
tmp_list = []
def inner(name):
tmp_list.append(1)
print(f"{name} -- {tmp_list}")
return inner
d1 = outer()
d2 = outer()
d1("d1")
d2("d2")
# 雖然代碼一樣,But every time the outer function is called it will be re-executed,創建一個新的tmp_list和inner
print(id(d1), id(d2))
# 匿名變量,All are placed in an anonymous space,所以地址一樣
print(id(outer()), id(outer()))
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-29-閉包和裝飾器/01、閉包.py
d1 -- [1]
d2 -- [1]
2138501753296 2138501753440
2138501753584 2138501753584
時間戳:
從1970年1月1日的0點0分0seconds The number of seconds elapsed so far
import time
def func1():
time.sleep(2)
print("func1....")
# 時間戳
# 從1970年1月1日的0點0分0seconds The number of seconds elapsed so far
t1 = time.time()
func1()
t2 = time.time()
print(f"函數執行時間{t2 - t1}")
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-29-閉包和裝飾器/02、裝飾器.py
func1....
函數執行時間2.0112464427948
@ :修飾符
import time
def runtime(func):
print("this is runtime")
def inner():
start = time.time()
func()
end = time.time()
print(f"Function execution took time{end - start}s")
return inner
@runtime # @modifiers to use decorators # runtime(func2)
def func2():
time.sleep(2)
print("func2....")
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-29-閉包和裝飾器/02、裝飾器.py
this is runtime
func2....
Function execution took time2.0134215354919434s
Decorators are a pattern,Its essence is a closure,
It does not change the source code of the function or class on the basis
Add functionality to a function or class
裝飾器有什麼用
• You can consider placing common functional code in the decorator to reduce program complexity.例如,Can be used with decorators:
• 引入日志
• 增加計時邏輯來檢測性能
• 給函數加入事務的能力
• 權限控制
# Decorator implements permission control
def login_required(func):
def inner(*args, **kwargs):
if username == "root":
print("歡迎")
result = func(*args, **kwargs)
return result
else:
return "權限不夠"
return inner
# Multiple decorators can be applied,但是要注意順序
# Executes from the inner expression of the topmost decorator
@login_required
def add(a, b):
time.sleep(2)
return a + b
username = input("請輸入用戶名:")
result = add(1, 2)
print(result)
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-29-閉包和裝飾器/02、裝飾器.py
請輸入用戶名:root
歡迎
3
import time
def runtime(func):
# Holds metadata about the function passed in,Assign its metadata to inner
@functools.wraps(func)
def inner(*args, **kwargs): # Make decorators more generic
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"函數 {func.__name__} 執行花了:{end -start}s")
return result
return inner
#
# a = runtime("name")
# add = a(add)
@runtime # add = runtime(add)
def add(a, b):
print("this is add ")
time.sleep(1)
return a+b
add(1, 2)
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-29-閉包和裝飾器/03、裝飾器參數.py
this is add
函數 add 執行花了:1.0147972106933594s
import functools
import time
def deco(name):
def runtime(func):
#Holds metadata about the function passed in,Assign its metadata to inner
@functools.wraps(func)
def inner(*args, **kwargs): #Make decorators more generic
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Function execution took time{end -start}s")
print(f"name is {name}")
return result
return inner
return runtime
# runtime = deco(name="sanle")
#func1 = runtime(func1)
@deco(name="sanle")
def func1():
time.sleep(3)
print("this is func1")
func1()
import time
class A:
def __init__(self, func):
self.func = func
def __call__(self, func):
def deco(*args, **kwargs):
start = time.time()
print("this is call")
result = func(*args, **kwargs)
end = time.time()
print(f"函數執行時間{end - start}")
return result
return deco
@A("name")
def func1():
time.sleep(2)
print("i am func1....")
func1()
def outer(cls):
def inner(*args, **kwargs):
print(f"class name is:{cls.__name__}")
return cls(*args, **kwargs)
return inner
@outer
class A:
def __init__(self, name):
self.name = name
print(type(A))
m = A("sc")
print(m.name)
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-29-閉包和裝飾器/05、裝飾類.py
<class 'function'>
class name is:A
sc
Day 31 (2022.2.12)
It was said that pygame Create