Python Language Fare un decoratore assomiglia alla funzione decorata


Esempio

I decoratori normalmente spogliano i metadati della funzione perché non sono gli stessi. Ciò può causare problemi quando si utilizza la meta-programmazione per accedere in modo dinamico ai metadati delle funzioni. I metadati includono anche le docstring della funzione e il suo nome. functools.wraps rende la funzione decorata simile alla funzione originale copiando diversi attributi alla funzione wrapper.

from functools import wraps

I due metodi di avvolgere un decoratore stanno ottenendo la stessa cosa nascondendo che la funzione originale è stata decorata. Non vi è alcun motivo per preferire la versione della funzione alla versione della classe a meno che non si stia già utilizzando uno sull'altro.

Come una funzione

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__

'test'

Come classe

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__

"Docstring of test".