Python裝飾器

定義

  本質就是函數,功能 爲其它函數添加附加功能python

  原則:閉包

  • 不修改被修飾函數的源代碼
  • 不修改被修飾函數的調用方式

  裝飾器的知識儲備
框架

  裝飾器 = 高階函數+函數嵌套+閉包   分佈式

  這裏面要明確高階函數的定義
ide

 1 import time#導入時間模塊兒
 2 def foo(func):  # func = test
 3     def bar(*args,**kwargs):
 4         start_time = time.time()
 5         res=func(*args,**kwargs)  # 這裏就是在運行test()  賦予變量
 6         stop_time = time.time()
 7         print("狼來了的時間爲%s" %(stop_time-start_time))
 8         return res # 返回test()的值
 9     return bar
10 @foo  # @foo 至關於 test=foo(test) 調用foo函數並將test傳給func
11 def test(name,age):
12     time.sleep(1)
13     print("名字叫%s年齡爲%s的狼來了" %(name,age))
14     return "村裏的羊被吃了"
15 ret = test("灰太狼",age=10)  # test()意在運行bar()   # 輸出res的返回值
16 print(ret)
裝飾器模型

分佈式講解:函數

高階函數的定義

    一、函數接收的參數是一個函數名  二、函數的返回值是一個函數名post

    以上條件任意知足一條,均可以稱之爲高階函數spa

 1 def foo():
 2     print('個人函數名字做爲參數傳給高階函數啦')
 3 def gao_jie1(func):   # 傳函數名  func = foo
 4     print('我就是高階函數1號,我接收的參數名是%s' %func)
 5     func() # 意在運行 foo()函數
 6 
 7 def gao_jie2(func): # func = foo
 8     print('我就是高階函數2號,個人返回值是%s' %func)
 9     return func  # 此時func爲返回foo的的內存地址
10 
11 gao_jie1(foo)
12 print(gao_jie2(foo))
13 
14 輸出
15 我就是高階函數1號,我接收的參數名是<function foo at 0x000001FDF179F598>
16 個人函數名字做爲參數傳給高階函數啦
17 我就是高階函數2號,個人返回值是<function foo at 0x000001FDF179F598>
18 <function foo at 0x000001FDF179F598>
高階函數示範
 1 import time
 2 def foo():
 3     time.sleep(2)
 4     print("狼來了")
 5 def test(func):  # func = foo
 6     start_time = time.time()
 7     func()  # func()意在調用 foo()函數
 8     stop_time = time.time()
 9     print("狼來的時間爲%s" %(stop_time-start_time))
10 test(foo) # 調用test()函數 並用函數名爲參數傳進去
將函數名爲參數傳給高階函數

    總結:一、函數接收的參數是一個函數名
code

        做用:在不修改函數源代碼的前提下添加新功能blog

        不足:改變了函數的調用方式

#高階函數應用2:把函數名當作參數傳給高階函數,高階函數直接返回函數名
import time
def foo():
    time.sleep(2)
    print("狼來了")
def test(func): # func = foo的內存地址
    start_time = time.time()
    return func # 返回值爲foo的內存地址
    stop_time = time.time()
    print("狼來的時間爲%s" %(stop_time-start_time))
foo = test(foo) # 調用test函數並將函數名foo作爲參數傳進去
print(foo) # 輸出返回值的結果 foo的內存地址
foo()  # 運行foo()函數

#沒有改變函數foo的調用方式,可是也沒有給函數增長新功能
函數返回值是函數名

   總結:二、函數的返回值是一個函數名

        做用:不修改函數的調用方式

        不足:沒有爲函數增長新的功能

函數嵌套

 1 def father(name):
 2     print('from father %s' %name)
 3     def son():
 4         print('from son')
 5         def grandson():
 6             print('from grandson')
 7         grandson()
 8     son()
 9 father('舒克')
10 
11 輸出
12 from father 舒克
13 from son
14 from grandson
函數嵌套

閉包

 1 '''
 2 閉包:在一個做用域裏放入定義變量,至關於打了一個包
 3 '''
 4 def father(name):
 5     def son():
 6         # name='alex'
 7         print('我爸爸是 [%s]' %name)
 8         def grandson():
 9         # name='wupeiqi'
10             print('我爺爺是 [%s]' %name)
11         grandson()
12     son()
13 father('舒克')
閉包示例

無參裝飾器=高階函數+嵌套函數

    基本框架

?
1
2
3
4
5
# 無參裝飾器,這是一個實現裝飾器最基本的框架
def timmer(func):
     def bar():
         func()
     return bar

    加入參數以後

?
1
2
3
4
5
# 帶參數裝飾器
def timmer(func):
     def bar( * args, * * kwargs):
         func( * args, * * kwargs)
     return bar

    加入時間功能

?
1
2
3
4
5
6
7
8
9
# 加一個時間的小功能
import time
def timmer(func):
      def bar( * args, * * kwargs):
          start_time = time.time()
          func( * args, * * kwargs)
         stop_time = time.time()
          print ( "狼來的時間爲%s" % (stop_time - start_time))
      return bar

    加入函數運行的返回值

?
1
2
3
4
5
6
7
8
9
10
# 加入函數返回值
import time
def timmer(func):
      def bar( * args, * * kwargs):
          start_time = time.time()
          res = func( * args, * * kwargs)
          stop_time = time.time()
          print ( "狼來的時間爲%s" % (stop_time - start_time))
         return res
      return bar

    使用裝飾器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import time
def timmer(func):
     def bar( * args, * * kwargs):
         start_time = time.time()
         res = func( * args, * * kwargs)
         stop_time = time.time()
         print ( "博爾特跑10米的時間爲%s" % (stop_time - start_time))
         return res
     return bar
# 使用裝飾器
def test():
     time.sleep( 1 )
     print ( "到達終點" )
     return "世界飛人"
test = timmer(test)
print (test())
 
輸出
到達終點
博爾特跑 10 米的時間爲 1.0006155967712402
世界飛人

    語法糖@

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time
def timmer(func):
     def bar( * args, * * kwargs):
         start_time = time.time()
         res = func( * args, * * kwargs)
         stop_time = time.time()
         print ( "博爾特跑10米的時間爲%s" % (stop_time - start_time))
         return res
     return bar
# 使用裝飾器
@timmer  # @timmer就至關於 test=timmer(test)
def test():
     time.sleep( 1 )
     print ( "到達終點" )
     return "世界飛人"
# test=timmer(test)
print (test())  # test()是在運行bar()函數

應用示例

user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'linhaifeng','passwd':'123'},
    {'name':'wupeiqi','passwd':'123'},
    {'name':'yuanhao','passwd':'123'},
    {'name':'病毒尖er','passwd':'123'},
]
current_user={'username':None,'login':False}

def auth_func(func):     # 用戶登錄驗證
    def bar(*args,**kwargs):
        if current_user["username"] and current_user["login"]:
            res = func(*args,**kwargs)
            return res
        for i in range(3):
            username = input("請輸入用戶名:").strip()
            passwd = input("請輸入密碼:").strip()
            for item in user_list:
                if username == item["name"] and passwd == item["passwd"]:
                    current_user["username"] = username
                    current_user["login"] = True
                    res=func(*args,**kwargs)
                    return res
        else:
            print("您輸入的用戶名或者密碼有誤")
    return bar
@auth_func # 至關於index=auth_func(index)
def index():
    print("歡迎來到京東商城" )
@auth_func # 至關於home=auth_func(home)
def home(name):
    print("%s歡迎回家" %name)
@auth_func # 至關於shop_car=auth_func()
def shop_car(name):
    print("%s的購物車是空的,趕忙購物咯" %name)

index()
home(current_user["username"])
shop_car(current_user["username"])
無參裝飾器

 

 1 user_list=[
 2     {'name':'alex','passwd':'123'},
 3     {'name':'linhaifeng','passwd':'123'},
 4     {'name':'wupeiqi','passwd':'123'},
 5     {'name':'yuanhao','passwd':'123'},
 6     {'name':'病毒尖er','passwd':'123'},
 7 ]
 8 current_user={'username':None,'login':False}
 9 def auth(auth_type="file"):
10     def auth_func(func):     # 用戶登錄驗證
11         def bar(*args,**kwargs):
12             if auth_type == "file":
13                 if current_user["username"] and current_user["login"]:
14                     res = func(*args,**kwargs)
15                     return res
16                 for i in range(3): # 給用戶三次重複輸入的機會 防止進入其它功能進入下一層
17                     username = input("請輸入用戶名:").strip()
18                     passwd = input("請輸入密碼:").strip()
19                     for item in user_list:
20                         if username == item["name"] and passwd == item["passwd"]:
21                             current_user["username"] = username
22                             current_user["login"] = True
23                             res=func(*args,**kwargs)
24                             return res
25                 else:
26                     print("您輸入的用戶名或者密碼有誤")
27             elif auth_type == "ldap":
28                 print("快點告訴你,你用我畫的蠟筆")
29                 res = func(*args,**kwargs)
30                 return res
31         return bar
32     return auth_func
33 @auth(auth_type="file")
34 def index():
35     print("歡迎來到京東商城" )
36 @auth(auth_type="ldap")  # 傳參數 類型對應
37 def home(name):
38     print("%s歡迎回家" %name)
39 @auth(auth_type="file")
40 def shop_car(name):
41     print("%s的購物車是空的,趕忙購物咯" %name)
42 
43 index()
44 home(current_user["username"])
45 shop_car(current_user["username"])
有參裝飾器
相關文章
相關標籤/搜索