程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python - closures and decorators

編輯:Python

目錄

一、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:裝飾類


一、python的閉包

示例1:閉包

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

示例2:形成閉包的條件

Form a closure condition:(缺一不可)
1、必須有一個內嵌函數
2、內函數必須引用外函數的變量
3、外函數必須返回內函數

示例3:After the closure is formed,Closure functions will get a non-null__closure__屬性

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

示例4:The difference between assigning a reference to a closure and calling an outer function directly

雖然代碼一樣,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

二、裝飾器

示例1:統計函數執行時間

時間戳:

        從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

示例2:Write a decorator that counts the runtime of a function

@ :修飾符

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

示例3:什麼是裝飾器

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:
• 引入日志
• 增加計時邏輯來檢測性能
• 給函數加入事務的能力
• 權限控制

示例4:用Decorator implements permission control

# 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

示例5:保留元數據

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()

示例6:用類實現裝飾器

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()

示例7:裝飾類

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


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved