python - Python 3 中的导入后 Hook

标签 python python-3.x python-import

我希望在导入特定模块时运行一些回调。例如(使用一个并不真正存在的假 @imp.when_imported 函数):

@imp.when_imported('numpy')
def set_linewidth(numpy):
    import shutil
    numpy.set_printoptions(linewidth=shutil.get_terminal_size()[0])

此功能是在 PEP 369: Post import hooks 中设计的但被撤回,原因是:

This PEP has been withdrawn by its author, as much of the detailed design is no longer valid following the migration to importlib in Python 3.3.

但是importlib没有明确的解决方案。如何使用 importlib 实现导入后 Hook ?

最佳答案

我会很震惊地发现这是执行此操作的最佳方法......但是,自早期的 python2.x 版本以来,猴子修补 __import__ 一直是支持的。我们可以在这里利用它:

try:
    import builtins  # python3.x
except ImportError:
    import __builtin__ as builtins  # python2.x
import sys
import collections

_builtin_import = builtins.__import__

def _my_import(name, globals=None, locals=None, fromlist=(), level=0):
    already_imported = name in sys.modules

    mod = _builtin_import(
        name,
        globals=globals,
        locals=locals,
        fromlist=fromlist,
        level=level)

    if not already_imported and name in _post_import_hooks:
        for hook in _post_import_hooks[name]:
            hook()
    return mod

builtins.__import__ = _my_import

_post_import_hooks = collections.defaultdict(list)

def on_import(name):
    def decorator(func):
        _post_import_hooks[name].append(func)
        return func
    return decorator

@on_import('numpy')
def print_hi():
    print('Hello Numpy')

print('before numpy')
import numpy
print('after numpy')

这个答案为注册回调创建了一个 super 简单的注册表。装饰器只是注册函数然后返回它。它不会做任何花哨的检查(例如,模块是否已经加载),但可以很容易地扩展来做到这一点。

显然不利的是,如果其他模块决定对 __import__ 进行猴子修补,那么您就不走运了——这个模块或另一个模块都可能最终损坏。

我已经测试过了,它似乎适用于 python2.x 和 python3.x。

关于python - Python 3 中的导入后 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40623889/

相关文章:

python - 将多个高斯拟合到 python 中的数据

python - 如何使用类型提示指定 "nullable"返回类型

python - 每组内累计运行百分比和每组降序排列python

python-3.x - 用另一个数据框的行部分替换数据框

python - 如何在pygame中添加残像?

python - 为什么导入的函数 "as"另一个名称保留其原始__name__?

python - 如何从兄弟目录导入python模块?

python - 使用 conda 和 poppler 安装后无法导入 pdftotext,Windows 10

python - 使用 Pandas 查找重复的行并将其 reshape 为一行

python - 无法从 Android 上的 Kivy 应用程序发送蓝牙