Pass-through/export 整个第三方模块(使用 __all__?)

Pass-through/export whole third party module (using __all__?)

我有一个模块包装另一个模块以在某些函数中插入一些垫片逻辑。包装模块使用我想公开的设置模块 mod.settings,但我不希望用户从那里导入它,以防将来我也想在那里填充一些东西。我希望他们导入 wrapmod.settings.

模块的导入和导出工作正常,但在客户端有点冗长。它导致必须写 settings.thing 而不是 thing

我希望用户能够执行 from wrapmod.settings import * 并获得与他们执行 from mod.settings import * 相同的结果,但现在只有 from wrapmod import settings 可用。我该如何解决这个问题?

如果我对情况的理解正确,您正在编写一个模块 wrapmod,旨在转换现有包 mod 的部分内容。您要转换的特定部分是子模块 mod.settings。您已经导入了 settings 模块并对其进行了更改,但即使它作为 wrapmod.settings 可用,您也不能在 from ... import ... 语句中使用该模块名称。

我认为解决这个问题的最佳方法是将修改后的模块插入新点名下的 sys.modules。这使得 Python 接受该名称是有效的,即使 wrapmod 不是真正的包。

所以 wrapmod 看起来像:

import sys

from mod import settings

# modify settings here

sys.modules['wrapmod.settings'] = settings   # add this line!

我最终为薄包装模块制作了一个代码生成器,因为 sys.module 黑客破坏了所有 IDE 集成。

from ... import mod

# this is just a pass-through wrapper around mod.settings
__all__ = mod.__all__

# generate pass-through wrapper around mod.settings; doesn't break IDE integration, unlike manual sys.modules editing.
if __name__ == "__main__":
    for thing in settings.__all__:
        print(thing + " = mod." + thing)

当 运行 作为脚本时,输出代码可以附加到该文件的末尾。