Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Comment fonctionne un décorateur de fonction ?

2 réponses
Avatar
jean-marc pouchoulon
bonjour à tous,
je m'interroge sur la différence entre ces deux codes
je cherche une logique à la transmission de la fonction au décorateur et
au role des () après le décorateur.
Un coup on transmet une fonction , l'autre coup c'est une condition et
la fonction est transmise au wrapper
C'est un peu trop magique pour moi

Merci de vos explications


def require_int (func):
def wrapper (arg):
assert isinstance(arg, int)
return func(arg)
return wrapper

@require_int
def meth (arg):
print arg
meth(1)
meth(a)
------------------------------------------------

def requis(expr):
def undecorateur(function):
def enveloppeur(*__args,**__kw):
assert eval(expr),"un argument svp!"
return function(*__args,**__kw)
return enveloppeur
return undecorateur

@requis("len(__args)==1")
def test(*args):
print args[0]

test("Hello world!")
test("je vous salue","bien bas")

2 réponses

Avatar
Amaury Forgeot d'Arc
bonjour à tous,
je m'interroge sur la différence entre ces deux codes
je cherche une logique à la transmission de la fonction au décorateur et
au role des () après le décorateur.
Un coup on transmet une fonction , l'autre coup c'est une condition et
la fonction est transmise au wrapper
C'est un peu trop magique pour moi

Merci de vos explications


def require_int (func):
def wrapper (arg):
assert isinstance(arg, int)
return func(arg)
return wrapper

@require_int
def meth (arg):
print arg
meth(1)
meth(a)
------------------------------------------------

def requis(expr):
def undecorateur(function):
def enveloppeur(*__args,**__kw):
assert eval(expr),"un argument svp!"
return function(*__args,**__kw)
return enveloppeur
return undecorateur

@requis("len(__args)==1")
def test(*args):
print args[0]

test("Hello world!")
test("je vous salue","bien bas")


Ce qu'on peut comparer dans ces deux morceaux de code, ce sont les
fonctions "wrapper" et "enveloppeur": elles prennent toutes deux la
place de la fonction à décorer.
On peut aussi mettre en parallèle "require_int" et "undecorateur": elles
prennent la fonction originale en paramètre, et renvoient une autre
fonction à la place. C'est ça, un décorateur.

Et le "requis" du deuxième exemple? cette fonction sert simplement à
créer un décorateur ("undecorateur") spécialisé pour le test demandé.
Alors que "require_int" est un décorateur câblé pour vérifier le type de
l'argument.

Dans tous les cas, quand on ne s'y retrouve plus, on peut se rappeler
qu'un décorateur n'est qu'un truc de syntaxe, et qu'on peut écrire comme
ceci:

def meth(arg):
print arg
meth = require_int(meth)


def test(*args):
print args[0]
test = requis("len(__args)==1")(test)

C'est tout pareil.

--
Amaury

Avatar
jean-marc pouchoulon
def test(*args):
print args[0]
test = requis("len(__args)==1")(test)

C'est tout pareil.

ok c'est clair

merci