¿Python3 decorando condicionalmente?

¿Es posible decorar una función basada en una condición?

a’la:

if she.weight() == duck.weight(): @burn def witch(): pass 

Me pregunto si podría usarse la lógica (¿cuándo se llama a la witch ?) Para averiguar si decorar a la witch con @burn ?

Si no, ¿es posible crear una condición dentro del decorador con el mismo efecto? ( witch se llama sin decoración.)

Puedes crear un decorador ‘condicional’:

 >>> def conditionally(dec, cond): def resdec(f): if not cond: return f return dec(f) return resdec 

Ejemplo de uso a continuación:

 >>> def burn(f): def blah(*args, **kwargs): print 'hah' return f(*args, **kwargs) return blah >>> @conditionally(burn, True) def witch(): pass >>> witch() hah >>> @conditionally(burn, False) def witch(): pass >>> witch() 

Los decoradores son solo azúcar sintáctica para redefinir la función, por ejemplo:

 def wrapper(f): def inner(f, *args): return f(*args) return lambda *args: inner(f, *args) def foo(): return 4 foo = wrapper(foo) 

Lo que significa que podría hacerlo de la manera anterior, antes de que existiera el azúcar sintáctico:

 def foo(): return 4 if [some_condition]: foo = wrapper(foo) 

Es posible habilitar / deshabilitar a los decoradores por reasignación.

 def unchanged(func): "This decorator doesn't add any behavior" return func def disabled(func): "This decorator disables the provided function, and does nothing" def empty_func(*args,**kargs): pass return empty_func # define this as equivalent to unchanged, for nice symmetry with disabled enabled = unchanged # # Sample use # GLOBAL_ENABLE_FLAG = True state = enabled if GLOBAL_ENABLE_FLAG else disabled @state def special_function_foo(): print "function was enabled"