天天看點

2021-03-09 進階函數作業題裝飾器

裝飾器

python 中支援特殊文法,在某個函數上方使用 ----> @

@ 函數名
def xxx():
    paas

python 内部會自動執行  函數名(xxx),執行之後,再把結果指派給XXX

相當于這樣的執行    xxx = 函數名(xxx)
           
  • 第一思路
def outer(origin):
    def inner():
        print('before')
        res = origin()
        print('after')
        return res
    return inner
    
def func():
    print('函數本尊')
    value= (11,22,33,44)
    return value

func = outer(func)
result = func()
print(result)
           
  • 第二思路
def outer(origin):
    def inner():
        print('before')
        res = origin()
        print('after')
        return res
    return inner
    
@outer
def func():
    print('函數本尊')
    value= (11,22,33,44)
    return value

result = func()
print(result)

           
  • 第三思路,需求: 三個函數,三個函數執行前後執行輸出“列印之前和之後”,或者10000個類似代碼要批量輸出某個功能。
    '''
    需求: 在函數執行前,輸出before,執行後輸出after
    
    '''
    def outer(origin):
        def inner(*args,**kwargs):
            print('before')
            res = origin(*args,**kwargs)
            print('after\n')
            return res
        return inner
    
    @outer
    def func1(a1):
        print('函數本尊func1')
        value= (11,22,33,44)
        return value
    
    @outer
    def func2(a1,a2):
        print('函數本尊func2')
        value= (11,22,33,44)
        return value
    
    @outer
    def func3(a1,a2,a3):
        print('函數本尊func3')
        value= (11,22,33,44)
        return value
    
    a = func1(11)
    b = func2(22,33)
    c = func3(33,44,[55,44])
               
    • 裝飾器擴充
      from flask import Flask
      
      app = Flask(__name__)
      
      def index():
          return '第一個頁面'
      
      
      app.add_url_rule('/index',view_func=index)
      
                 
      • functools的用途,不加這個會出錯(内部會讀取___name___,且__name__ 重名的話會報錯),是以需要規範自己的寫法
        import functools
        
        def auth(func):
            @functools.wraps(func)
            def inner(*args,**kwargs):
                ''' 哇哈哈,這是注釋内容呀'''
                res = func(*args,**kwargs)
                return res
            return inner
                   

進階函數作業題

1、編寫一個裝飾器,可以實作執行函數func時,先執行函數内部代碼,再輸出after

import functools

def outer(function):
    @functools.wraps(function)
    def inner(*args,**kwargs):
        print('before')
        res = function(*args,**kwargs)
        return res
    return inner


@outer
def func(a1):
    return a1 + '這裡是a1函數'
@outer
def base(a1,a2):
    return a1 + a2 + '這裡是base的函數'
@outer
def foo(a1,a2,a3,a4):
    return a1 + a2 + a3 + a4 + '這裡是foo'

func('baba')

base('a1','a2')

foo('a1','a2','a3','a4')
           

2、編寫一個裝飾器,可以實作:将被裝飾的函數執行5次,每次執行函數的結果按照順序放到清單中,最終傳回清單。

import random
import functools

def five_times(function):
    @functools.wraps(function)
    def inner(*args,**kwargs):
        data_list = []
        for i in range(5):
            res = function(*args,**kwargs)
            data_list.append(res)
        return data_list
    return inner

@five_times
def func1():
    return random.randint(1,4)

result = func1()
print(result)
           

3、編寫一個裝飾器,可以實作:檢查檔案所在路徑是否存在,如果不存在自動建立檔案夾(確定寫入檔案不會報錯)

import os
import functools

def gard(function):
    @functools.wraps(function)
    def inner(path):

        # 擷取路徑
        folder_path = path.rsplit('/',1)[0]
        if not os.path.exists(folder_path):
            os.makedirs(path)

        res = function(path)
        return res
    return inner

@gard
def write_user_info(path):
    file_object = open(path,mode='w',encoding='utf-8')
    file_object.write('新建立内容')
    file_object.close()

write_user_info(r'D:/py2021')