I am defining several functions in a python package composed of several modules that represent separate components of a simulation model.
To execute the simulation model, the package is imported and the functions along with their __name__
are extracted by iterating through the modules' __dict__
like this:
import model # The package containing python modules
import inspect
import types
# Get the modules defined in the package
modules = [v for v in vars(model).values() if isinstance(v, types.ModuleType)]
funcs = {}
# Iterate through modules in python package
for module in modules:
# Go through objects in module `__dict__`
for name, obj in vars(module).items(): # decorated functions no longer appear here
# Check for functions
if isinstance(obj, types.FunctionType):
# Make sure that the function is defined within the model package
mod, *sub_mod = inspect.getmodule(obj).__name__.split('.')
if mod == model.__name__:
# Store the function along with its name
funcs[name] = obj
However, when I am debugging this code I'm noticing that some functions that should be in vars(module).items()
are not. This happened after applying an lru_cache
decorator to some of the functions, which are precisely the ones not showing up.
Why after applying a decorator to some of the functions in the python package do they not show up in the module's __dict__
for which they are defined?
Is there a way to still be able to apply the decorator and have the functions show up in vars(module).items()
?
The problem is that when you wrap a function with lru_cache, the result is only a callable object, and not a function. The precise type is
functools._lru_cache_wrapper
.I originally posted this as a comment. pbreach's solution was to replace
types.FunctionType
with(types.FunctionType, functools._lru_cache_wrapper)
, becausecallable()
was too broad a net.