【24】Python裝飾器筆記

來源:互聯網
上載者:User

標籤:return   傳回值   inpu   pre   sse   username   wrap   全域   固定   

裝飾器
定義:本職是函數,(裝飾其他函數)就是為其他函數添加附加功能。
原則:
1.不能修改被裝飾的函數的原始碼
2.不能修改被裝飾函數的調用的方式

先來一個直觀感受import timedef timmer(func): ##    def warpper(*args,**kwargs):        start_time=time.time()        func()  ##run  test1()        stop_time=time.time()        print("the func time is %s"%(start_time-stop_time))    return warpper@timmer  #@加函數名,即可調用函數def test1():  ###原始碼    time.sleep(3)    print("in the test1")test1()

實現裝飾器的知識儲備:
1.函數即"變數"
2.高階函數
3.嵌套函數(函數裡面def聲明一個函數叫嵌套函數,調用函數不叫嵌套)

下面進行一波實驗:如下三種結果(驗證1.函數即“變數”)A.輸出報錯沒有bar函數def foo():    print("in the foo")    bar()foo()B.成功def bar():    print("in the bar")def foo():    print("in the foo")    bar()foo()C.輸出報錯,沒找到定義的bar函數def foo():    print("in the foo")    bar()foo()def bar():    print("in the bar")

在將函數即“變數”的時候,先講下python記憶體儲存變數的機制。
當設定一個變數x=1時,記憶體看成一個大house,這時候大house會騰出一個房間將變數值1放入這個房間,並貼上x的門牌號。
如果是x=1,y=x,那就是變數值1這個房間將會有兩個門牌號,即x&y。:
而在python記憶體的回收機制中,當你的房間沒有門牌號時,它就會預設回收。這樣可以節約空間。而當兩個或多個變數值都一樣時,它不會給你建立N個房間,而是同一個房間內貼上N個門牌號。

凡是也有例外,有人就會說了,那就不會有沒有變數名的變數了嗎?這個在python中,還真有即匿名函數lambda。當lambda x:x*3,結果是佔用的記憶體位址。

這裡的
print(“in the poo”)
bar()
就是函數體相當於變數存放在記憶體中。poo()就是門牌號,當執行A時之所以會報錯,就是因為沒有找到bar的函數體。而C雖然定義了bar()但是定義的位置不對,函數都是從上往下讀取,當執行poo()之前並沒有定義,所以會報錯找不到bar

2.高階函數(又分以下兩種)

a:把一個函數名當做實參傳遞給另外一個函數import timedef bar():    time.sleep(3)    print("in the bar")def test1(func):  ##根據test1(bar)的調用可以看出,這裡的func = bar。這就是把bar函數名傳遞給func當test1的實參    start_time=time.time()    func() #run bar()    stop_time=time.time()    print("the func run time is %s"%(stop_time-start_time))test1(bar)b:傳回值中包含函數名import timedef bar():    time.sleep(3)    print("in the bar")def test2(func):    print(func)    return func  #f返回bar的記憶體值print(test2(bar))t=test2(bar) #test2執行結果賦值給了t,相當於把bar(賦值給了t,當使用t()時,就是在執行bar函數t()  #run bar()

3.嵌套函數 (在一個函數體內用def聲明一個函數叫嵌套。調用不叫嵌套)

#局部即變數def foo():    def bar():        print("in the bar")    bar() ##想要輸出print結果就需要一層層的調用foo()#局部作用和全域範圍的訪問順序x=0def boo():    def daa():        x=2        def son():            x=3            print(x)        son()    daa()boo()猜測下這裡的輸出結果是:

下面寫個簡單的裝飾器。(高階函數+嵌套函數=》裝飾器)
不設定函數實參

import timedef timer(func):  ##func=test1=test2    def deco():        start_time=time.time()        func()  ##func=test1 =test2        stop_time=time.time()        print("the funce run time is %s" %(stop_time-start_time))    return decodef test1():    time.sleep(3)    print("in the test1")@timerdef test2():    time.sleep(3)    print("in the test2")test1=timer(test1)test1() ##-->decotest2()

當設定test實參時,可以這樣寫。deco() func()裡面都直接*args,***kwargs不限量。如果具體某一個參數,那就可以修改為具體的。

import timedef timer(func):    def deco(*args,**kwargs):        start_time=time.time()        func(*args,**kwargs)        stop_time=time.time()        print("the funce run time is %s" %(stop_time-start_time))    return decodef test1():    time.sleep(3)    print("in the test1")@timer #非固定參數namedef test2(name):    time.sleep(3)    print("in the test2",name)test1=timer(test1)test1() ##-->decotest2("alex")

類比遠端登入與本地登入實驗:

user,passwd="alex","abc"def auth(auth_type):    print("auth>>>",auth_type)    def outer_wrapper(func):        def wrapper(*args,**kwargs):            print("*args,**kwargs",*args,**kwargs)            if auth_type=="local":                username=input("Input user: ").strip()                password=input("Input password: ").strip()                if username==user and password==passwd:                    print("\033[32;1mUser has passed authentication\033[0m")                    res=func(*args,**kwargs)                    return res                else:                    exit("\033[31;1mIminvalid username or password\033[0m")            elif auth_type=="ldap":                print("不會")        return wrapper    return outer_wrapperdef index():    print("welcome to index page")@auth(auth_type="local")  ##本地驗證登入def home():    print("welcome to home page")    return  "from home"@auth(auth_type="ldap")  ##遠端驗證登入def dds():    print("welcome to dds page")index()print(home())dds()

【24】Python裝飾器筆記

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.