1. 程式人生 > >裝飾器基本原理

裝飾器基本原理

put *args raw sleep 因此 實參 eas 函數的調用 username

#coding=utf-8
#裝飾器本質為函數(用來裝飾其他函數)為其他函數添加附加功能
#原則:1、不能修改被裝飾函數的源代碼
#2、不能修改函數的調用方式
#實現裝飾器
#1、函數即變量
#2、高階函數
#a、把一個函數名當做實參傳入另一個函數
#b、返回值中包含函數名(不修改函數的調用方式)
#3、嵌套函數
#高階函數+嵌套函數 = 裝飾器

import time
#裝飾器實例
# def timmer(func):
#     def warpper(*args,**kwargs):
#         start_time = time.time()
#         func()
#         stop_time = time.time()
#         print ("the funtion run time is %s"%(stop_time-start_time))
#     return warpper
# @timmer
# def fun1():
#     time.sleep(3)
#     print ("123456")
#
# fun1()
#
# def fun2():
#     print ("this is fun2")
#     fun3()

#匿名函數
# a = lambda x:x*3
# print a(3)

#高階函數實例

# def fun1():
#     print ("123")
#
# def fun2(def1):
#     start_time = time.time()
#     time.sleep(3)
#     def1()
#     end_time = time.time()
#     print("fun run time is %s"%(start_time-end_time))
#
#
# fun2(fun1)   #調用fun1的一種方法加裝飾的

# def fun3():
#     print ("456")
#
# def fun4(def1):
#     print time.time()
#     return def1
#
# x=fun4(fun3)
# x()
#
# fun3 = fun4(fun3)
# fun3()

#嵌套函數實例

# def fun5():
#     print ("this is fun 5")
#     def fun6():
#         print ("this is fun 6")
#     fun6()
#
# fun5()

def fun7():
    time.sleep(4)
    print ("this is fun7")

def fun8():
    time.sleep(6)
    print ("this is fun 8")

def deco(funname):                                     #只用到了高階函數的第一個特性 把一個函數名當做實參傳入另一個函數
    start_time = time.time()
    funname()
    end_time = time.time()
    print ("run time is %s"%(start_time-end_time))

# deco(fun7)                                           #此處給函數添加了新功能,但是調用方式變了
# deco(fun8)

def deco(funname):                                     #只用到了高階函數的第二個特性 返回值中包含函數名(不修改函數的調用方式)可以實現不更改函數的調用方式
    start_time = time.time()
    return funname
    end_time = time.time()
    print ("run time is %s"%(start_time-end_time))
#
# fun7 = deco(fun7)
# fun7()                                               #此處調用方式沒變但是沒加入新功能
# fun8 = deco(fun8)
# fun8()

#接下來介入嵌套函數
# def fun9():
#     def fun10():
#         """
#         pass
#         :return:
#         """
#即
def fun9(funname):
    def fun10():
        start_time = time.time()
        funname()
        end_time = time.time()
        print ("run time is %s" % (start_time - end_time))
    return fun10

# fun7 = fun9(fun7)
# fun7()
#相當於
# @fun9
#  def fun7():
#         psss
@fun9    #這一步進行的操作就是執行fun7 = fun9(fun7),而不會重新定義下面這個函數了
def fun7():
    time.sleep(4)
    print ("this is fun7")

#fun7()  #事實上執行的是fun10函數

@fun9
def fun11(time):
    print ("123")
#執行fun11,會報錯
#fun11(1234)
#執行fun11相當於執行fun10所以可以在fun10上加參數
def fun9(funname):
    def fun10(*args,**kwargs):
        start_time = time.time()
        funname()
        end_time = time.time()
        print ("run time is %s" % (start_time - end_time))
    return fun10

user = "zte"
passw = "zte"

def ayth(arg1):
    print arg1
    def outweappen(funname):
        def wrapper(*args,**kwargs):
            username = raw_input("please input username: ").strip()
            password = raw_input("please in put password:").strip()
            if username ==user and passw == password:
                print("welcome")
                return funname(*args,**kwargs)

            else:
                exit()
        return wrapper
    return outweappen


@ayth
def index():
    print ("one")

@ayth
def home():
    print ("two")
    return "1241"  #這裏需要返回值,因此要在wrapper內加入return funname()

@ayth(arg1="abc")     #如果加了參數的話,就要使用多層嵌套
def blog():
    print ("thrree")
blog()
"""
@ayth(arg1="abc") 相當於blog = ayth((arg1="abc"))=outweappen()加了括號,相當於要執行outweappen函數,而此函數返回了wrapper
blog() =  wrapper()

"""

裝飾器基本原理