python函式式程式設計之裝飾器 二

2022-05-26 13:12:10 字數 3708 閱讀 2507

以前用裝飾器,都是定義好了裝飾器後,使用@裝飾器名的方法寫入被裝飾函式的正上方

在這裡,定義的裝飾器都是沒有引數的

在定義裝飾器的函式的時候,沒有在括號裡定義引數,這就叫做無參裝飾器

既然有無參裝飾器,那麼當然也就會有有參裝飾器

定義乙個普通的裝飾器

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...