裝飾器,匿名函式

林堯彬發表於2019-03-18

裝飾器

裝飾器的開放封閉原則:

裝飾器對擴充套件是開放的,對修改原始碼是封閉的,不能改變原函式的呼叫方式

 1 基本完整的裝飾器函式示例
 2 import time                                       #時間模組
 3 def warpper(f):                                 #接受被裝飾的函式記憶體地址
 4     def inner(*args,**kwargs):           #接受被裝飾函式的引數  inner裡面函式是擴充套件的功能
 5         start_time = time.time()           #計時功能
 6         ret = f(*args,**kwargs)           #呼叫被裝飾的函式,帶著被裝飾函式的引數
 7         end_time = time.time()             #計時功能
 8         print('%s函式的執行時間:%s'%(f.__name__,end_time-start_time))
 9                                                         #計時功能
10         return ret                                  #被裝飾函式的返回值
11     return inner                                   #通過這一步令func() = inner()
12 
13 @warpper                                         #語法糖,相當於func = warpper(func)
14 def func(*args,**kwargs):                #被裝飾函式
15     print(args)                                    #主函式功能
16     print('這是主功能')                          #主函式功能
17     time.sleep(1)                                #計時功能
18     return '你好'                                  #被裝飾函式的返回值,返回到inner裡的ret
19 #其實語法糖縮寫的函式位置在這裡,此處相當於有一個func = warpper(func)
20 ret = func(5)                                    #func(5) = inner(5)  此處的ret來自inner
21 print(ret)                                          #ret是func的return,但不由func返回
def wrapper1(func1):  # func1 = f原函式
    def inner1():
        print('wrapper1 ,before func')  # 2
        func1()
        print('wrapper1 ,after func')  # 4
    return inner1

def wrapper2(func2):  # func2 == inner1
    def inner2():
        print('wrapper2 ,before func')  # 1
        func2()  # inner1
        print('wrapper2 ,after func')  # 5
    return inner2


@wrapper2  # f = wrapper2(f) 裡面的f == inner1  外面的f == inner2
@wrapper1  # f = wrapper1(f) 裡面的f == func1  外面的 f == inner1
def f():
    print('in f')  # 3

f()  # inner2()
多個裝飾器裝飾一個函式
def wrapper_out(n):
    def wrapper(f):
        def inner(*args,**kwargs):
            username = input('請輸入使用者名稱:').strip()
            password = input('請輸入密碼:').strip()
            with open(n,encoding='utf-8') as f1:
                for line in f1:
                    user,pwd = line.strip().split('|')
                    if username == user and password == pwd:
                        print('登陸成功')
                        ret = f(*args,**kwargs)
                        return ret
                return False
        return inner
    return wrapper

"""
看到帶引數的裝飾器分兩步執行:
    1. 執行wrapper_out('騰訊') 這個函式,把相應的引數'騰訊' 傳給 n,並且得到返回值 wrapper函式名。
    2. 將@與wrapper結合,得到我們之前熟悉的標準版的裝飾器按照裝飾器的執行流程執行。
"""


@wrapper_out('qq')
def qq():
    print('成功訪問qq')


@wrapper_out('tiktok')
def tiktok():
    print('成功訪問抖音')

qq()
tiktok()
# 開發思路:增強耦合性
帶引數的裝飾器

 

內建函式  :

匿名函式lambda: 為了解決那些功能很簡單的需求而設計的一句話函式

引數可以有多個,用逗號隔開

匿名函式不管邏輯多複雜,只能寫一行,且邏輯執行結束後的內容就是返回值

返回值和正常的資料一樣可以是任意資料型別

排序函式sorted:

字典排序返回的就是排序後的key

和lambda組合使用:

篩選過濾filter:

對映函式map

改寫成lambda

reduce:

reduce的使用方式

reduce(函式名,可迭代物件)  這兩個引數必須要有,缺一不行

和lambda一起使用

在Python2.x版本中recude是直接 import就可以的, Python3.x版本中需要從functools這個包中匯入

龜叔本打算將 lambda 和 reduce 都從全域性名字空間都移除, 輿論說龜叔不喜歡lambda 和 reduce

最後lambda沒刪除是因為和一個人寫信寫了好多封,進行交流然後把lambda保住了

 

 

 

轉載於:https://www.cnblogs.com/biulo/p/10555345.html

相關文章