1. 程式人生 > >Python基礎知識之裝飾器decorator

Python基礎知識之裝飾器decorator

定義

本質是函式,(裝飾其他函式)為其他函式新增附加功能。

原則

  1. 不能修改被裝飾的函式的原始碼
  2. 不能修改被裝飾的函式的呼叫方式

實現裝飾器知識儲備

  • 函式即“變數”
  • 高階函式
  • 巢狀函式

高階函式+巢狀函式=》裝飾器

1. 函式即“變數”:

定義一個函式就相當於定義一個變數,即將函式體賦值給一個變數名。python的記憶體回收機制規定:當儲存在記憶體中的內容沒有對應的變數名指定時,則當記憶體回收機制定期清理記憶體的時候則回收記憶體。

2. 高階函式:

  • 把一個函式名當作實參傳給另外一個函式(在不修改被裝飾函式原始碼的前提下新增新功能)
    def bar():
        print("in the bar")

    #  test1就是一個高階函式
    def test1(func):
        print(func)
        func()


    test1(bar)
  • 返回值中包含函式名
    (不修改函式的呼叫方式)

3. 巢狀函式:

        在一個函式的函式體內用def宣告一個新的函式。
        def func1():
            def func2():
                pass

裝飾器案例剖析

import
time # 這裡的timer就是一個裝飾器 def timer(func): def deco(*args, **kwargs): start_time = time.time() func(*args, **kwargs) end_time = time.time() print("the func run time is %s" %(end_time-start_time)) return deco # 裝飾器的呼叫 @timer # test1 = timer(test1) def test1():
time.sleep(3) print("in the test1") test1()

裝飾器高階案例

user, passwd = 'bear', 'abc123'
def auth(auth_type):
    print("auth func:",auth_type)
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):
            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("User has passed authtication")
                    res = func(*args, **kwargs)
                    return res
                else:
                    exit("Invalid username or password")
            elif auth_type == "ldap":
                print("搞毛線ldap,不會。。。。")
        return wrapper
    return outer_wrapper


def index():
    print("welcome to index page")

@auth(auth_type = "local")  # home = wrapper()
def home():
    print("welcome to home page")
    return "from home"
@auth(auth_type = "ldap")
def bbs():
    print("welcome to bbs page")


print(home())  #wapper()