柠檬班python自动化视频百度云_python自动化装逼指南1-装饰器详解
這篇文章由檸檬班Python全棧自動化學員
重慶--圓滾滾童鞋分享的一篇技術共享文章。
話不多說,直接上文章
一. 裝飾器原則:
1. 不能修改被裝飾函數的源代碼
2. 不能修改被裝飾函數的調用方法
二. 知識儲備
1. 函數及變量
2. 高階函數(滿足一個即可)
2.1 函數名做函數實參
# import time
# def bar():
# time.sleep(3)
# print('in the bar')
#
# def test1(func):
# start_time=time.time()
# func() #run bar
# stop_time=time.time()
# print("the func run time is %s" %(stop_time-start_time))
#
# test1(bar)
# bar()
可以實現在不改變源代碼的情況下,為函數添加功能,但是改變了函數的調用方式
2.2 函數返回值中包含函數名
import time
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func)
return func
# print(test2(bar))
bar=test2(bar)
bar() #run bar
實現了直接通過bar(),不改變函數的調用方式,增加函數的功能
3. 嵌套函數
在一個函數的函數體內,用def去聲明一個函數,而不是其調用他
def grandpa():
x = 1
def dad():#在這里只是聲明了一個函數,但是沒有調用他,所以最后什么都不打印
x =2
def son():
x = 3
print(x)
son()
#dad()
grandpa()
三. python的內存回收機制:
python的解釋器中有一個引用計數的概念,python通過這個引用機制來實現內存的回收
四. 匿名函數
calc = lambda x:x*3
print(calc(3))
#結果為9
匿名函數沒有函數名,聲明后會立馬被回收掉,但是將其賦值給一個變量之后,就不會被立馬回收掉
五. 裝飾器演化進程
1. 利用嵌套函數、高階函數實現裝飾器
1.1
import time
def deco(func):
def timer():
start_time = time.time()
func()
end_time = time.time()
print("\033[32;1mthe func runs %s"%(end_time-start_time))
return timer
def test1():
time.sleep(1)
print("in the test1")
test1 = deco(test1)
test1()
這種方式多了test1=deco(test1)的步驟
1.2 python@語法糖
python解釋器提供了一個語法糖,來代替test1 = deco(test1)的功能
import time
def deco(func):
def timer():
start_time = time.time()
func()
end_time = time.time()
print("\033[32;1mthe func runs %s"%(end_time-start_time))
return timer
@deco#等于是執行了test1 = deco(test1)
def test1():
time.sleep(1)
print("in the test1")
test1()
1.3 帶參數裝飾器實現
但是上面的裝飾器只是適用于無參函數,對于有參函數就會報錯,要想實現對帶參函數實現裝飾器功能,需要在裝飾器函數中帶上參數,注意@test就是執行了test1=deco(test1),實際上是執行了嵌套的timer函數,所以在timer函數中帶*args,**kwags參數,就可以實現利用裝飾器修飾所有的帶參以及不帶參函數
import time
def timer(func):
def deco(*arg, **kwargs):
start_time = time.time()
func(*arg, **kwargs)
end_time = time.time()
print("\033[34;1mthe func runs %s"%(end_time-start_time))
return deco
@timer #等于是執行了test1 = timer(test1)
def test1():
time.sleep(0.5)
print("in the test1")
@timer
def test2(name):
time.sleep(0.5)
print("in the test2", name)
test1()
test2("gupan")
1.4 python裝飾器實現選擇執行
如果遇到遇到如下的場景,對于一個網站來說,如果是用戶普通的登陸,只需要調用本地的認證服務器進行判斷,如果涉及到充值等金錢相關業務,就需要調用第三方的認證接口,進行身份信息的驗證,這就需要在定義引用裝飾器的時候就傳入參數@deco(auth_type = "local"),但是在講解裝飾器時,我們看到,函數第一層已經傳入了函數名作為參數,第二層傳入業務函數的參數,這樣就需要我們再添加一層
python的解釋器對@語法糖作出如下規定
如果@deco(auth_type="lcoal"),"local"傳入了最外面一層,第二層傳入其修飾的函數的函數名,第三層傳入了其所修飾函數實參
import time
user,passwd = 'alex','abc123'
def auth(auth_type):#先傳入auth_type參數
print("auth func:",auth_type)
def outer_wrapper(func):#傳入所修飾函數的函數名
def wrapper(*args, **kwargs):#傳入函數被裝飾函數實參
print("wrapper func args:", *args, **kwargs)
if auth_type == "local":
username = input("Username:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("\033[32;1mUser has passed authentication\033[0m")
res = func(*args, **kwargs) # from home
print("---after authenticaion ")
return res
else:
exit("\033[31;1mInvalid username or password\033[0m")
elif auth_type == "ldap":
print("搞毛線ldap,不會。。。。")
return wrapper
return outer_wrapper
def index():
print("welcome to index page")
@auth(auth_type="local") # home = wrapper()
def home():
print("welcome to home page")
return "from home"
@auth(auth_type="ldap")
def bbs():
print("welcome to bbs page")
index()
print(home()) #wrapper()
bbs()
總結
以上是生活随笔為你收集整理的柠檬班python自动化视频百度云_python自动化装逼指南1-装饰器详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 公共互联网网络安全突发事件应急预案_安徽
- 下一篇: python3源码剖析_T-SNE源码剖