I have a module which contains a lot of functions (more than 25). I want to add a common decorator function to each of these functions. The normal way to do is to add a @dec
I think applying a decorator en-masse such that it's not obvious where you will go looking to find out about the function (at its definition) is generally a bad idea. Explicit is better than implicit, and all that.
If you want to apply the decorator to some third party module's functions, without modifying the third-party code, here is how I would do it:
# my_wrapper_module.py
import some_module
import functools
def some_decorator(func):
@functools.wraps(func):
def wrapper(*args, **kwargs):
...
return wrapper
FUNCTION_NAMES = [
'some_func_1',
'some_func_2',
'some_func_3',
...
]
for name in FUNCTION_NAMES:
globals()[name] = some_decorator(getattr(some_module, name))
And then use these functions elsewhere by doing from my_wrapper_module import some_func_2
, etc.
For me, this has the following advantages:
my_wrapper_module
to see what I'm calling, and that I'm not using the undecorated versions of the functionsmy_wrapper_module
what functions are being exported, that they originally come from some_module
, and that they all have the same decorator appliedsome_module
directly isn't silently and inexplicably affected; this could be particularly important if the third-party code is more than one moduleBut if what you're trying to do is hack a third-party library so that internal calls are affected, then this is not what you want.
If your decorator is called my_decorator
### Decorate all the above functions
import types
for k,v in globals().items():
if isinstance(v, types.FunctionType):
globals()[k] = my_decorator(v)
You could also apply this to the module after importing it
import othermodule
import types
for k,v in vars(othermodule).items():
if isinstance(v, types.FunctionType):
vars(othermodule)[k] = my_decorator(v)