国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

9.4 定義一個帶參數(shù)的裝飾器

2018-02-24 15:27 更新

問題

你想定義一個可以接受參數(shù)的裝飾器

解決方案

我們用一個例子詳細(xì)闡述下接受參數(shù)的處理過程。假設(shè)你想寫一個裝飾器,給函數(shù)添加日志功能,當(dāng)時允許用戶指定日志的級別和其他的選項。下面是這個裝飾器的定義和使用示例:

from functools import wraps
import logging

def logged(level, name=None, message=None):
    """
    Add logging to a function. level is the logging
    level, name is the logger name, and message is the
    log message. If name and message aren't specified,
    they default to the function's module and name.
    """
    def decorate(func):
        logname = name if name else func.__module__
        log = logging.getLogger(logname)
        logmsg = message if message else func.__name__

        @wraps(func)
        def wrapper(*args, **kwargs):
            log.log(level, logmsg)
            return func(*args, **kwargs)
        return wrapper
    return decorate

# Example use
@logged(logging.DEBUG)
def add(x, y):
    return x + y

@logged(logging.CRITICAL, 'example')
def spam():
    print('Spam!')

初看起來,這種實現(xiàn)看上去很復(fù)雜,但是核心思想很簡單。最外層的函數(shù) logged() 接受參數(shù)并將它們作用在內(nèi)部的裝飾器函數(shù)上面。內(nèi)層的函數(shù) decorate() 接受一個函數(shù)作為參數(shù),然后在函數(shù)上面放置一個包裝器。這里的關(guān)鍵點是包裝器是可以使用傳遞給 logged() 的參數(shù)的。

討論

定義一個接受參數(shù)的包裝器看上去比較復(fù)雜主要是因為底層的調(diào)用序列。特別的,如果你有下面這個代碼:

@decorator(x, y, z)
def func(a, b):
    pass

裝飾器處理過程跟下面的調(diào)用是等效的;

def func(a, b):
    pass
func = decorator(x, y, z)(func)

decorator(x, y, z) 的返回結(jié)果必須是一個可調(diào)用對象,它接受一個函數(shù)作為參數(shù)并包裝它,可以參考9.7小節(jié)中另外一個可接受參數(shù)的包裝器例子。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號