将decorator应用于函数似乎将其从模块__dict__中删除

时间:2017-01-04 19:57:25

标签: python python-module python-decorators lru python-packaging

我在python包中定义了几个函数,这些函数由几个模块组成,这些模块代表了模拟模型的独立组件。

要执行模拟模型,将导入包,并通过迭代模块“__name__来提取函数及其__dict__

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

但是,当我调试此代码时,我注意到应该在vars(module).items()中的某些函数不是。这是在将lru_cache装饰器应用于某些功能之后发生的,这些功能恰好是未显示的功能。

为什么在将一个装饰器应用到python包中的某些函数后,它们是否会出现在模块的__dict__中?它们是否被定义?

有没有办法仍然可以应用装饰器并让功能显示在vars(module).items()

1 个答案:

答案 0 :(得分:1)

问题是当你用lru_cache包装一个函数时,结果只是一个可调用的对象,而不是一个函数。确切的类型是functools._lru_cache_wrapper

我最初将此作为评论发布。 pbreach的解决方案是将types.FunctionType替换为(types.FunctionType, functools._lru_cache_wrapper),因为callable()网络过于宽泛。