Surtout dans les décorateurs de fonction, vous créez et retournez souvent une fonction qui encapsule la fonction de modification que vous recevez en tant qu'argument, mais parfois vous voulez que la signature de la fonction d'encapsulation soit la même que la fonction encapsulée. Dans Python 3.4 et versions ultérieures, cette implémentation est possible en utilisant un décorateur appelé wraps fourni par les functools de la bibliothèque standard.
Dans l'exemple ci-dessous, la fonction funny_function
modifiée avec le décorateur ʻargs_as_ints (c'est-à-dire le
wrapper modifié avec
functools.wraps) a la même signature que la fonction modifiée
funny_function, mais tous Convertissez l'argument en ʻint
et faites le même calcul pour la fonction d'origine.
python
# Source: https://stackoverflow.com/questions/147816/preserving-signatures-of-decorated-functions
import functools
def args_as_ints(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
args = [int(x) for x in args]
kwargs = dict((k, int(v)) for k, v in kwargs.items())
return func(*args, **kwargs)
return wrapper
@args_as_ints
def funny_function(x, y, z=3):
"""Computes x*y + 2*z"""
return x*y + 2*z
Après avoir été qualifié, la fonction funny_function
a un membre appelé __wrapped__
, qui conserve la fonction d'origine.
Pour inspecter la signature d'une fonction, utilisez la bibliothèque standard inspect. Vous pouvez utiliser la fonction signature
fournie par inspect pour récupérer la signature de la fonction en tant qu'objetSignature
. Le code suivant garantit que la signature funny_function
est la même avant et après la modification.
python
>>> from inspect import signature
>>> str(signature(funny_function))
'(x, y, z=3)'
>>> signature(funny_function) == signature(funny_function.__wrapped__)
True