问题
Is it possible to decorate a function based on a condition?
a'la:
if she.weight() == duck.weight():
@burn
def witch():
pass
I'm just wondering if logic could be used (when witch
is called?) to figure out whether or not to decorate witch
with @burn
?
If not, is it possible to create a condition within the decorator to the same effect? (witch
being called undecorated.)
回答1:
You can create a 'conditionally' decorator:
>>> def conditionally(dec, cond):
def resdec(f):
if not cond:
return f
return dec(f)
return resdec
Usage example follows:
>>> 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()
回答2:
Decorators are just syntactical sugar for re-defining the function, ex:
def wrapper(f):
def inner(f, *args):
return f(*args)
return lambda *args: inner(f, *args)
def foo():
return 4
foo = wrapper(foo)
Which means that you could do it the old way, before the syntactical sugar existed:
def foo():
return 4
if [some_condition]:
foo = wrapper(foo)
回答3:
It is possible to enable/disable decorators by reassignment.
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"
来源:https://stackoverflow.com/questions/3773555/python3-decorating-conditionally