J'essaie de créer une fonction qui complète d'autres fonctions pour mon diplôme universitaire. Par exemple, je voudrais appeler la round_sqrt = round(sqrt)
et quand j'appelle la round_sqrt(5)
elle doit me montrer 2
Au lieu de 2.23606797749979
. Ce que j'essaie, c'est ceci:
def rounding(funct):
return round(funct)
mais cela ne fonctionne pas.
EDIT: La fonction ne doit avoir qu'un seul paramètre. Par exemple, le début de la fonction doit être
def rounding(func):
donc dans cette fonction, la fonction funct
doit être arrondie. donc quand j'appelle rounding(abs)(3.2)
il me montre 3
.
Pour votre exemple spécifique, vous pouvez écrire
def round_sqrt(x):
return round(sqrt(x))
réponse d'Alex généralise cela; il définit une fonction qui crée round_sqrt
pour vous. Si la fonction est déjà définie, il vous suffit de la passer comme argument à rounder
:
round_sqrt = rounder(sqrt)
Bien sûr, vous n'avez pas besoin de définir round_sqrt
Si vous ne le souhaitez pas. rounder(sqrt)(3.2)
peut être appelée directement, bien qu'il soit beaucoup plus efficace de sécuriser la valeur de retour de rounder
si vous prévoyez de l'utiliser plusieurs fois, plutôt que de la redéfinir à chaque fois.
Sinon, la syntaxe du décorateur est juste courte (en utilisant l'exemple d'Alex)
def adder(x, y):
return x + y
adder = rounder(adder)
Comme je l'ai dit dans mon commentaire, il s'agit d'un exemple de mise en œuvre de la composition. Mathématiquement, la composition est simple, car les fonctions mathématiques prennent toujours un seul argument et renvoient un seul argument. Ainsi, la composition de deux fonctions f
et g
pourrait toujours être définie simplement comme
def compose(f, g):
def h(x): # The name doesn't matter
return f(g(x))
return h
Alors
round_sqrt = compose(round, sqrt)
(Ignorant toutes sortes de problèmes pratiques concernant l'implémentation, Python pourrait en théorie même fournir un opérateur Unicode ∘
Pour les fonctions: round_sqrt = round ∘ sort
. Explication pourquoi cela ne se produira pas dépasse le cadre de cette réponse.)
En Python, cependant, les fonctions sont beaucoup plus compliquées. Ils peuvent prendre plusieurs arguments, ils peuvent accepter un nombre arbitraire d'arguments et d'arguments de mots-clés arbitraires, et bien que chacun renvoie techniquement une seule valeur, cette valeur peut être un tuple considéré comme plusieurs valeurs ou un dict
. Par conséquent, vous pouvez vous attendre à plusieurs façons de passer la valeur de retour de g
à une fonction f
, plus que ce qui peut être facilement hébergé dans une simple fonction compose
.
Vous devriez vérifier les fermetures:
def rounder(func):
def inner(*args, **kwargs):
return round(func(*args, **kwargs))
return inner
Ensuite, vous pouvez décorer des fonctions en utilisant le @
personnage:
@rounder
def adder(x, y):
return x + y
print(adder(1.1, 2.2))
les sorties 3
Supplémentaire:
functools.wraps
dans votre fermeture afin de ne pas perdre d'informations (par exemple docstring, nom de la fonction) sur la fonction d'origine.La composition des fonctions n'est pas prise en charge nativement en Python. Vous pouvez utiliser un décorateur selon @ la solution d'Alex . Vous pouvez définir une nouvelle fonction explicitement selon @ solution de chepner .
Ou vous pouvez utiliser une bibliothèque tierce. Par exemple, via toolz.compose
:
from toolz import compose
def adder(x, y):
return x + y
round_adder = compose(round, adder)
round_adder(1.1, 2.2) # 3