使裝飾器看起來像裝飾功能

裝飾器通常會刪除功能後設資料,因為它們不相同。當使用超程式設計來動態訪問函式後設資料時,這可能會導致問題。後設資料還包括函式的文件字串及其名稱。 functools.wraps 通過將幾個屬性複製到包裝函式,使裝飾函式看起來像原始函式。

from functools import wraps

包裝裝飾器的兩種方法在隱藏原始功能已被裝飾時實現了同樣的目的。沒有理由將函式版本更喜歡類版本,除非你已經使用了另一個版本。

作為一個功能

def decorator(func):
    # Copies the docstring, name, annotations and module to the decorator
    @wraps(func)
    def wrapped_func(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapped_func

@decorator
def test():
    pass

test.__name__

‘測試’

作為一個類

class Decorator(object):
    def __init__(self, func):
        # Copies name, module, annotations and docstring to the instance.
        self._wrapped = wraps(func)(self)
        
    def __call__(self, *args, **kwargs):
        return self._wrapped(*args, **kwargs)

@Decorator
def test():
    """Docstring of test."""
    pass

test.__doc__

‘測試檔案。’