gpt4 book ai didi

python - 在 Python 中递归地重新加载包(及其子模块)

转载 作者:太空狗 更新时间:2023-10-29 21:56:57 25 4
gpt4 key购买 nike

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

import foobar

import importlib
importlib.reload(foobar)

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

带包:

  • 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.

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

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

注意事项:

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

    (目前使用importlib)

  • 允许这可能需要对模块本身进行一些编辑。
  • 假设不使用通配符导入(from foobar import *),因为它们可能会使重新加载逻辑复杂化。

最佳答案

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

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

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 - 在 Python 中递归地重新加载包(及其子模块),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28101895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com