Python 入門之 Python三大器 之 裝飾器


Python 入門之 Python三大器 之 裝飾器

1、開放封閉原則:

(1)代碼擴展進行開放

​ 任何一個程序,不可能在設計之初就已經想好了所有的功能並且未來不做任何更新和修改。所以我們必須允許代碼擴展、添加新功能。

(2)修改源代碼是封閉

​ 當我們寫的一個函數,已經交付給其他人使用,如果這個時候我們對函數內部進行修改,或者修改了函數的調用方式,很有可能影響其他已經在使用該函數的用戶。

在不修改源代碼及調用方式,對功能進行額外的添加就是開放封閉原則

2、裝飾器:

在不改變原被裝飾的函數的源代碼以及調用方式下,為其添加額外的功能。

(1)初識裝飾器:

​ 裝飾(額外功能) 器(工具:函數)

import time

def index():
    time.sleep(2)  #
    print("這是小明寫的功能")

def func():
    time.sleep(1)  #
    print("這是小剛寫的功能")

def red():
    time.sleep(2)  #
    print("這是小紅寫的功能")

start_time = time.time()  # 時間戳
index()
print(time.time() - start_time)

start_time = time.time()  # 時間戳
func()
print(time.time() - start_time)

start_time = time.time()  # 時間戳
red()
print(time.time() - start_time)

( 此方法返回的是格林尼治時間,是此時此刻距離1970年1月1日0點0分0秒的時間秒數.也叫時間戳,它是一直變化的。)

import time
print(time.time())

以上代碼重復,繁瑣

改進:(將求時間寫在一個函數中,函數就是以功能為導向,減少重復代碼)

import time

def index():
    time.sleep(2)  #
    print("這是小明寫的功能")

def func():
    time.sleep(1)  #
    print("這是小剛寫的功能")

def red():
    time.sleep(2)  #
    print("這是小紅寫的功能")

def times(func):
    start_time = time.time()  # 時間戳
    func()
    print(time.time() - start_time)

times(index)
times(func)

改進:

第一版裝飾器
import time
def func():
    time.sleep(1)  #
    print("這是小剛寫的功能")

def red():
    time.sleep(2)  #
    print("這是小紅寫的功能")

def index():
    time.sleep(2)  #
    print("這是小明寫的功能")

def times(func):
    def foo():
        start_time = time.time()  # 時間戳  被裝飾函數執行前干的事
        func()
        print(time.time() - start_time) #   被裝飾函數執行后干的事
    return foo           # 不能加括號

index = times(index)       # 不能加括號
index()
func = times(func)
func()

(2)語法糖 (Python 幫我們做的一個東西)

要將語法糖寫在被裝飾函數的最上方
def warpper(f):
    def inner():
        print("111")
        f()
        print("222")
    return inner

# python幫咱們做的一個東西,語法糖
@warpper  # func = warpper(func)
def func():
    print("被裝飾的函數1")

@warpper  # index = warpper(index)
def index():
    print("被裝飾的函數2")

func()

def warpper(f):
    def inner(*args,**kwargs):
        print("被裝飾函數執行前")
        ret = f(*args,**kwargs)
        print("被裝飾函數執行后")
        return ret
    return inner

@warpper
def func(*args,**kwargs):
    print(f"被裝飾的{args,kwargs}")
    return "我是func函數"

@warpper
def index(*args,**kwargs):
    print(11111)

print(func(1,2,3,4,5,6,7,8,a=1))

(3)標准版的裝飾器:

def wrapper(func):
    def inner(*args,**kwargs):
        '''執行被裝飾函數之前的操作'''
        ret = func()
        '''執行被裝飾函數之后的操作'''
        return ret
    return inner

這個就是標准的裝飾器,完全符合代碼開放封閉原則。

4、裝飾器進階

(1)有參裝飾器

def auth(argv):
    def warpper(func):
        def inner(*args,**kwargs):
            if argv == "博客園":
                print("歡迎登錄博客園")
                user = input("user:")
                pwd = input("pwd:")
                if user == 'alex' and pwd == "dsb":
                    func(*args,**kwargs)
            elif argv == "碼雲":
                print("歡迎登錄碼雲")
                user = input("user:")
                pwd = input("pwd:")
                if user == 'alex' and pwd == "jsdsb":
                    func(*args, **kwargs)

        return inner
    return warpper

def foo():
    print("被裝飾的函數")

msg = input("請輸入您要登錄的名字:")
a = auth(msg)
foo = a(foo)
foo()
def auth(argv):
    def wrapper(func):
        def inner(*args,**kwargs):
            if argv:
                print("我加上功能了!")
                func(*args,**kwargs)
            else:
                func(*args,**kwargs)
        return inner
    return wrapper

https://www.cnblogs.com/

@auth(True)   # @auth == foo = wrapper(foo) = auth(True)   flask框架
def foo():
    print("這是一個點燃")
foo()

(2)多個裝飾器裝飾一個函數

多個裝飾器裝飾一個函數,先執行離被裝飾函數最近的裝飾器

def auth(func):             # wrapper1裝飾器里的 inner
    def inner(*args,**kwargs):
        print("額外增加了一道 鍋包肉")
        func(*args,**kwargs)
        print("鍋包肉 38元")
    return inner

def wrapper1(func):        # warpper2裝飾器里的 inner
    def inner(*args,**kwargs):
        print("額外增加了一道 刺生")
        func(*args,**kwargs)
        print("刺生 白吃")
    return inner

def wrapper2(func):         # 被裝飾的函數foo
    def inner(*args,**kwargs):
        print("額外增加了一道 麻辣哥")
        func(*args,**kwargs)
        print("難以下嘴")
    return inner
    
def foo(): 
    print("這是一個元寶蝦飯店")
    
foo = wrapper2(foo) # inner = wrapper2(foo)
foo = wrapper1(foo) # inner = wrapper1(inner)
foo = auth(foo)     # inner = auth(inner)
foo()               # auth里邊的inner()
def auth(func):            # wrapper1裝飾器里的 inner
    def inner(*args,**kwargs):
        print(123)
        func(*args,**kwargs)
        print(321)
    return inner


def wrapper1(func):         # warpper2裝飾器里的 inner
    def inner(*args,**kwargs):
        print(111)
        func(*args,**kwargs)
    return inner


def wrapper2(func):          # 被裝飾的函數foo
    def inner(*args,**kwargs):
        print(222)
        func(*args,**kwargs)
        print(567)
    return inner


@auth                 # 1           7
@wrapper1             #   2       6
@wrapper2             #    3    5
def foo():            #      4
    print("www.baidu.com")
foo()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM