Python 入門之 Python三大器 之 裝飾器
1、開放封閉原則:
(1)代碼擴展進行開放
任何一個程序,不可能在設計之初就已經想好了所有的功能並且未來不做任何更新和修改。所以我們必須允許代碼擴展、添加新功能。
(2)修改源代碼是封閉
當我們寫的一個函數,已經交付給其他人使用,如果這個時候我們對函數內部進行修改,或者修改了函數的調用方式,很有可能影響其他已經在使用該函數的用戶。
在不修改源代碼及調用方式,對功能進行額外的添加就是開放封閉原則
2、裝飾器:
在不改變原被裝飾的函數的源代碼以及調用方式下,為其添加額外的功能。
(1)初識裝飾器:
裝飾(額外功能) 器(工具:函數)
import time
def index():
time.sleep(2) #
print("這是小明寫的功能")
def func():
time.sleep(1) #
print("這是小剛寫的功能")
def red():
time.sleep(2) #
print("這是小紅寫的功能")
start_time = time.time() # 時間戳
index()
print(time.time() - start_time)
start_time = time.time() # 時間戳
func()
print(time.time() - start_time)
start_time = time.time() # 時間戳
red()
print(time.time() - start_time)
( 此方法返回的是格林尼治時間,是此時此刻距離1970年1月1日0點0分0秒的時間秒數.也叫時間戳,它是一直變化的。)
import time
print(time.time())
以上代碼重復,繁瑣
改進:(將求時間寫在一個函數中,函數就是以功能為導向,減少重復代碼)
import time
def index():
time.sleep(2) #
print("這是小明寫的功能")
def func():
time.sleep(1) #
print("這是小剛寫的功能")
def red():
time.sleep(2) #
print("這是小紅寫的功能")
def times(func):
start_time = time.time() # 時間戳
func()
print(time.time() - start_time)
times(index)
times(func)
改進:
第一版裝飾器
import time
def func():
time.sleep(1) #
print("這是小剛寫的功能")
def red():
time.sleep(2) #
print("這是小紅寫的功能")
def index():
time.sleep(2) #
print("這是小明寫的功能")
def times(func):
def foo():
start_time = time.time() # 時間戳 被裝飾函數執行前干的事
func()
print(time.time() - start_time) # 被裝飾函數執行后干的事
return foo # 不能加括號
index = times(index) # 不能加括號
index()
func = times(func)
func()
(2)語法糖 (Python 幫我們做的一個東西)
要將語法糖寫在被裝飾函數的最上方
def warpper(f):
def inner():
print("111")
f()
print("222")
return inner
# python幫咱們做的一個東西,語法糖
@warpper # func = warpper(func)
def func():
print("被裝飾的函數1")
@warpper # index = warpper(index)
def index():
print("被裝飾的函數2")
func()
def warpper(f):
def inner(*args,**kwargs):
print("被裝飾函數執行前")
ret = f(*args,**kwargs)
print("被裝飾函數執行后")
return ret
return inner
@warpper
def func(*args,**kwargs):
print(f"被裝飾的{args,kwargs}")
return "我是func函數"
@warpper
def index(*args,**kwargs):
print(11111)
print(func(1,2,3,4,5,6,7,8,a=1))
(3)標准版的裝飾器:
def wrapper(func):
def inner(*args,**kwargs):
'''執行被裝飾函數之前的操作'''
ret = func()
'''執行被裝飾函數之后的操作'''
return ret
return inner
這個就是標准的裝飾器,完全符合代碼開放封閉原則。
4、裝飾器進階
(1)有參裝飾器
def auth(argv):
def warpper(func):
def inner(*args,**kwargs):
if argv == "博客園":
print("歡迎登錄博客園")
user = input("user:")
pwd = input("pwd:")
if user == 'alex' and pwd == "dsb":
func(*args,**kwargs)
elif argv == "碼雲":
print("歡迎登錄碼雲")
user = input("user:")
pwd = input("pwd:")
if user == 'alex' and pwd == "jsdsb":
func(*args, **kwargs)
return inner
return warpper
def foo():
print("被裝飾的函數")
msg = input("請輸入您要登錄的名字:")
a = auth(msg)
foo = a(foo)
foo()
def auth(argv):
def wrapper(func):
def inner(*args,**kwargs):
if argv:
print("我加上功能了!")
func(*args,**kwargs)
else:
func(*args,**kwargs)
return inner
return wrapper
https://www.cnblogs.com/
@auth(True) # @auth == foo = wrapper(foo) = auth(True) flask框架
def foo():
print("這是一個點燃")
foo()
(2)多個裝飾器裝飾一個函數
多個裝飾器裝飾一個函數,先執行離被裝飾函數最近的裝飾器
def auth(func): # wrapper1裝飾器里的 inner
def inner(*args,**kwargs):
print("額外增加了一道 鍋包肉")
func(*args,**kwargs)
print("鍋包肉 38元")
return inner
def wrapper1(func): # warpper2裝飾器里的 inner
def inner(*args,**kwargs):
print("額外增加了一道 刺生")
func(*args,**kwargs)
print("刺生 白吃")
return inner
def wrapper2(func): # 被裝飾的函數foo
def inner(*args,**kwargs):
print("額外增加了一道 麻辣哥")
func(*args,**kwargs)
print("難以下嘴")
return inner
def foo():
print("這是一個元寶蝦飯店")
foo = wrapper2(foo) # inner = wrapper2(foo)
foo = wrapper1(foo) # inner = wrapper1(inner)
foo = auth(foo) # inner = auth(inner)
foo() # auth里邊的inner()
def auth(func): # wrapper1裝飾器里的 inner
def inner(*args,**kwargs):
print(123)
func(*args,**kwargs)
print(321)
return inner
def wrapper1(func): # warpper2裝飾器里的 inner
def inner(*args,**kwargs):
print(111)
func(*args,**kwargs)
return inner
def wrapper2(func): # 被裝飾的函數foo
def inner(*args,**kwargs):
print(222)
func(*args,**kwargs)
print(567)
return inner
@auth # 1 7
@wrapper1 # 2 6
@wrapper2 # 3 5
def foo(): # 4
print("www.baidu.com")
foo()
