以前用裝飾器,都是定義好了裝飾器後,使用@裝飾器名
的方法寫入被裝飾函式的正上方
在這裡,定義的裝飾器都是沒有引數的
在定義裝飾器的函式的時候,沒有在括號裡定義引數,這就叫做無參裝飾器
既然有無參裝飾器,那麼當然也就會有有參裝飾器
定義乙個普通的裝飾器
db_path = "db.txt"
login_dic =
def auth(func):
if login_dic['user'] and login_dic['status']:
res = func(*args, **kwargs)
return res
name = input("your name:").strip()
password = input("your password:").strip()
with open(db_path, "r", encoding="utf-8") as f:
user_dic = eval(f.read())
if name in user_dic and password == user_dic[name]:
print("login ok")
login_dic['user'] = name
login_dic['status'] = true
res = func(*args, **kwargs)
return res
else:
print("login error")
@auth
def index():
print("welcome to index page")
@auth
def home(name):
print("welcome to %s home page" % name)
index()
home()
上面的例子是乙個典型的基於檔案的認證方式的裝飾器
在生產環境中,使用者的認證方式可能有很多種,比如還有ldap和資料庫的認證方式
如果想把上面的**修改,新增基於不同認證方式的使用者認證
db_path = "db.txt"
login_dic =
def deco(auth_type):
def auth(func):
if auth_type == "file":
if login_dic['user'] and login_dic['status']:
res = func(*args, **kwargs)
return res
name = input("your name:").strip()
password = input("your password:").strip()
with open(db_path, "r", encoding="utf-8") as f:
user_dic = eval(f.read())
if name in user_dic and password == user_dic[name]:
print("login ok")
login_dic['user'] = name
login_dic['status'] = true
res = func(*args, **kwargs)
return res
else:
print("login error")
elif auth_type == 'ldap':
print("ldap認證方式")
elif auth_type == "sql":
print("資料庫的認證方式")
else:
print("不知道的認證方式")
return auth
有參裝飾器的呼叫@deco(auth_type="file")
def index():
print("welcome to index page")
@deco(auth_type="abc")
def home(name):
print("welcome to %s home page" % name)
index()
home()
在上面的例子裡,deco(auth_type="file")
這個函式的執行以後就得到了auth函式
,但是現在得到的auth函式跟以前的auth函式是不一樣的
,現在的auth函式內部新增了認證方式這樣乙個引數
,
這樣新增auth_type引數後的結果就相當於加在index函式和home函式正上方的是auth函式
,這樣就為最開始時的auth函式新增了乙個引數
先定義3個函式,現在想做的是只需要使用者輸入字串,就執行對應的函式
可以通過為每個函式新增裝飾器的功能,把普通函式新增到函式字典中,然後到函式字典中找到輸入字串對應的函式位址,加括號就可以執行
了
類似於
func_dic =
def f1():
print("f1 func")
def f2():
print("f2 func")
def f3():
print("f3 func")
這裡就要使用到有參裝飾器
定義有參裝飾器
def make_func_dic(key):
def deco(func):
func_dic[key] = func
return deco
用裝飾器make_func_dic裝飾函式func_dic = {}
def make_func_dic(key):
def deco(func):
func_dic[key] = func
return deco
@make_func_dic("f1") # 等同於deco(f1)
def f1():
print("f1 func")
@make_func_dic("f2") # 等同於deco(f2)
def f2():
print("f2 func")
@make_func_dic("f3") # 等同於deco(f3)
def f3():
print("f3 func")
列印func_dic,得到結果
可以看到func_dic字典中,每個字串對應的是相應字串的函式的記憶體位址
這樣想執行f1函式,只需要把func_dic中的"f1"的值加括號執行就可以了
然後使使用者輸入字串,執行字串對應的函式
while true:
cmd=input(">>: ").strip()
if cmd in func_dic:
func_dic[cmd]()
這樣就可以得到想要的結果了
這樣做的好處:只需要輸入對應的字串,就可以執行對應的函式,不需要使用if和elif對輸入的字串進行一條一條的判斷
了
這就是使用裝飾器在**級別達到函式的路由功能
python函式式程式設計之裝飾器 二
以前用裝飾器,都是定義好了裝飾器後,使用 裝飾器名的方法寫入被裝飾函式的正上方 在這裡,定義的裝飾器都是沒有引數的 在定義裝飾器的函式的時候,沒有在括號裡定義引數,這就叫做無參裝飾器 既然有無參裝飾器,那麼當然也就會有有參裝飾器 定義乙個普通的裝飾器db path db.txt login dic ...
python 函式式程式設計 高階函式 裝飾器
coding gb2312 coding utf 8 高階函式 import math def is sqr x y int math.sqrt x return x y y print filter is sqr,range 1,101 返回函式 作用 延遲執行 def calc prod lst...
Python學習筆記 函式式程式設計 裝飾器
根據廖雪峰python教程整理 由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2013 12 25 f now f 2013 12 25 函式物件有乙個 name 屬性,可以拿到函式的名字 now.name now f.name now...