在 Python 中递归地重新加载包(及其子模块) [英] Reloading packages (and their submodules) recursively in Python

查看:39
本文介绍了在 Python 中递归地重新加载包(及其子模块)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Python 中,您可以按如下方式重新加载模块...

In Python you can reload a module as follows...

import foobar

import importlib
importlib.reload(foobar)

这适用于 .py 文件,但对于 Python 包,它只会重新加载包,不会任何嵌套的子模块.

This works for .py files, but for Python packages it will only reload the package and not any of the nested sub-modules.

带包裹:

  • foobar/__init__.py
  • foobar/spam.py
  • foobar/eggs.py

Python 脚本:

import foobar

# assume `spam/__init__.py` is importing `.spam`
# so we dont need an explicit import.
print(foobar.spam)  # ok

import importlib
importlib.reload(foobar)
# foobar.spam WONT be reloaded.

并不是说这是一个错误,但有时重新加载包及其所有子模块很有用.(例如,如果您想在脚本运行时编辑模块).

Not to suggest this is a bug, but there are times its useful to reload a package and all its submodules. (If you want to edit a module while a script runs for example).

在 Python 中递归重新加载包有哪些好方法?

What are some good ways to recursively reload a package in Python?

注意事项:

  • 为了这个问题的目的,假设最新的 Python3.x

  • For the purpose of this question assume the latest Python3.x

(目前使用 importlib)

推荐答案

这是一个递归加载包的函数.仔细检查重新加载的模块是否在使用它们的模块中更新,并检查了无限递归问题.

Heres a function that recursively loads a package. Double checked that the reloaded modules are updated in the modules where they are used, and that issues with infinite recursion are checked for.

一个重构是它需要在一个包上运行(无论如何只对包有意义)

One restruction is it needs to run on a package (which only makes sense for packages anyway)

import os
import types
import importlib


def reload_package(package):
    assert(hasattr(package, "__package__"))
    fn = package.__file__
    fn_dir = os.path.dirname(fn) + os.sep
    module_visit = {fn}
    del fn

    def reload_recursive_ex(module):
        importlib.reload(module)

        for module_child in vars(module).values():
            if isinstance(module_child, types.ModuleType):
                fn_child = getattr(module_child, "__file__", None)
                if (fn_child is not None) and fn_child.startswith(fn_dir):
                    if fn_child not in module_visit:
                        # print("reloading:", fn_child, "from", module)
                        module_visit.add(fn_child)
                        reload_recursive_ex(module_child)

    return reload_recursive_ex(package)

# example use
import os
reload_package(os)

这篇关于在 Python 中递归地重新加载包(及其子模块)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆