1. 程式人生 > >學習python第十三天,函式5 裝飾器

學習python第十三天,函式5 裝飾器

定義:裝飾器本質是函式,(裝飾其他函式)就是為其他函式新增附加功能
原則:1、不能修改被裝飾的函式的原始碼
2、不能修改裝飾的函式的呼叫方式

實現裝飾器知識儲備
1函式即變數
2、高階函式,滿足2個條件之一 1、把一個函式名當做實參傳給另外一個函式。2、返回值中包含函式名
(1、在不修改被裝飾的函式的原始碼的情況下,為其新增功能 2、不能修改函式的呼叫方式)
3、巢狀函式
高階函式+巢狀函式=》裝飾器
python記憶體回收機制,匿名函授和變數名沒有的情況下會被回收

def foo():
    print('in the foo')
    bar()
def bar():
    print('in the bar')
foo()
import time

def bar():
    time.sleep(0.5)
    print('in the bar')


def test1(func):
    start_time=time.time()
    print(func)
    time.sleep(0.5)
    func()
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))


test1(bar)#列印記憶體地址,呼叫方式改變了


import time

def bar():#定義原始函式
    time.sleep(0.5)#停止0.5秒
    print('in the bar')#定義過程
def test2(func):#定義裝飾器函式
    print(func)#定義過程
    return func#返回值“func”
print(test2(bar))#列印函式test2在bar中的記憶體地址
bar=test2(bar)#重新定義變數bar=函式test2以bar為實參
bar()#run bar#執行bar

  

巢狀函式:在一個函式的體內用def去宣告一個函式

def foo():
    print('in the foo')
    def bar():#在一個函式的體內用def去宣告一個函式
        print('in the bar')

    bar()
foo()
x=0
def gramdpa():
    x=1
    def dad():
        x=2
        def son():
            x=3
            print(x)
        son()
    dad()
gramdpa()

import time

  


裝飾器1——>無引數裝飾器(包含高階\巢狀函式) 要實現的功能是檢視“原始碼”程式運行了多少時間
def timer(func):#定義一個名為timer的函式,引數為func,timer(test1)把test1的記憶體地址傳給了func
    def deco():#宣告一個新的函式deco,函式的巢狀,他的作用
        start_time=time.time()#開始時間
        func()#等於執行run test1  適用無引數的原始碼
        stop_time=time.time()#結束時間
        print('the func run time is %s'%(stop_time-start_time))#列印...
    return deco#高階函式返回值中有函式deco記憶體地址

@timer
#原始碼
def test1(): #定義名為test1函式
    time.sleep(1)#等3秒
    print('in the test1')#函式過程 列印...
print(timer(test1))
test1=timer(test1)
test1()#--->執行deco

  

裝飾器2-->含多個引數(包含高階\巢狀函式) 要實現的功能是檢視“原始碼”程式運行了多少時間
import time
def timer(func):#定義一個名為timer的函式,引數為func,timer(test1)把test1的記憶體地址傳給了func
    def deco(*args,**kwargs):#宣告一個新的函式deco,函式的巢狀,他的作用
        start_time=time.time()#開始時間
        func(*args,**kwargs)#等於run test1  *args,**kwargs適用任何引數的原始碼
        stop_time=time.time()#結束時間
        print('the func run time is %s'%(stop_time-start_time))#列印...
    return deco#高階函式返回值中有函式deco記憶體地址

@timer
原始碼
def test1(): #定義名為test1函式
    time.sleep(1)#等3秒
    print('in the test1')#函式過程 列印...
print(timer(test1))
test1=timer(test1)
test1()#--->執行deco


@timer
def test2(name,age):#定義名為test2函式,含有name引數
    print("test2:",name,age)#列印 ...

test1()
test2("dream",22)#對應原始碼加入引數才能執行

  

裝飾器3--輸入使用者名稱密碼,(原始碼沒有返回資料的裝飾器)

import time
user,passwd='dream','133456'#預設密碼
def auth(func):
    def wrapper(*args,**kwargs):
        print("wrapper func args:",*args,**kwargs)
        username=input("Username:").strip()#移除空格和回車字元
        password=input("Password:").strip()
        if user==username and passwd==password:#驗證使用者名稱和密碼
            print('\033[32;1mUser has passed authentication\033[0m')
            func(*args,**kwargs)#執行原始碼
        else:
                exit('\33[31;1mInvalid username or password\033[0m')#否則退出
    return wrapper

@auth
def index():
    print('welcome to index page')
@auth
def home():
    print("welcome to home page")

@auth
def bbs():
    print("welcome to home page")

# index()
# home()
# bbs()

  



#裝飾器4--輸入使用者名稱密碼,原始碼含有返回資料的裝飾器

import time
user,passwd='dream','133456'#預設密碼
def auth(func):
    def wrapper(*args,**kwargs):
#        print("wrapper func args:",*args,**kwargs)
        username=input("Username:").strip()#移除空格和回車字元
        password=input("Password:").strip()
        if user==username and passwd==password:#驗證使用者名稱和密碼
            print('\033[32;1mUser has passed authentication\033[0m')
            res=func(*args,**kwargs)#定義一個變數
            return res

        else:
                exit('\33[31;1mInvalid username or password\033[0m')#否則退出
    return wrapper

@auth
def index():
    print('welcome to index page')
@auth
def home():
    print("welcome to home page")
    return "from home"

@auth
def bbs():
    print("welcome to home page")

# #index()
# print(home())
# #bbs()

  

裝飾器5--輸入使用者名稱密碼,判斷本地認證和遠端認證

import time
user,passwd='dream','133456'#預設密碼
def auth(auth_type):
    print("auth func:",auth_type)
    def outer_wrapper(func):
        def wrapper(*args,**kwargs):#定義wrapper函式帶有兩個函式
            print("wrapper func args:",*args,**kwargs)
            if auth_type=='local':
                username=input("Username:").strip()#移除空格和回車字元
                password=input("Password:").strip()
                if user==username and passwd==password:#驗證使用者名稱和密碼
                    print('\033[32;1mUser has passed authentication\033[0m')
                    res=func(*args,**kwargs)#執行原始碼
                    print('---after authenticaion')
                    return res
                else:
                    exit('\33[31;1mInvalid username or password\033[0m')#否則退出

            elif auth_type=="ldap":
                print("行不通")
        return wrapper

    return outer_wrapper

def 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 bbs():
    print("welcome to home page")
#
#index()
home()
bbs()