【问题标题】:Python - View an imported module's dotted importPython - 查看导入模块的虚线导入
【发布时间】:2018-03-28 06:51:06
【问题描述】:

我想获取从任意模块m 导入的所有模块。 当m 以如下方式导入模块时:

from a.b import c

或:

import a.b.c as c

(其中ab 是包,c 是模块)

dir(m) 的结果将包含 c(除其他外)。

但是,当我使用:

import a.b.c

dir(m) 的结果将包含a,而不是c

我也尝试在导入m 后迭代sys._getframe(1).f_locals.items(),但得到了相同的结果。 我怎样才能拥有以这种方式导入cm 对象,知道它实际上导入了c

【问题讨论】:

  • 不是很清楚你到底想要什么,如果c是一个模块那么c就是模块本身,反正取决于你的项目结构和每个包的__init__.py的内容
  • 对不起,让我澄清一下:我想从任意模块m 中获取所有导入的模块。现在如果m 以这种方式导入c (import a.b.c),我不会通过迭代dir(m) 得到c。假设我不知道ca.b 里面——我怎么能得到它?

标签: python python-import python-module


【解决方案1】:

您可以使用ast module 来解析模块的源代码并提取导入:

import sys
import ast
import inspect


def find_imports(module):
    code = inspect.getsource(module)
    tree = ast.parse(code)

    imports = set()
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            imports.update(alias.name for alias in node.names)
        elif isinstance(node, ast.ImportFrom):
            imports.add(node.module)
            for alias in node.names:
                module_name = '{}.{}'.format(node.module, alias.name)
                if module_name in sys.modules:
                    imports.add(module_name)

    return imports

请记住,这仅在模块的源代码以纯 Python 代码形式提供时才有效。


以这个模块为例:

from os.path import isfile
from importlib import util
import urllib.request as urlquest
import urllib.parse
import sys

这个模块的输出是

{'sys', 'urllib.request', 'os.path', 'importlib', 'importlib.util', 'urllib.parse'}

注意事项:

  1. 此代码还捕获函数中的导入,而不仅仅是全局范围内的导入。
  2. 如果代码执行像from module import submodule 这样的导入,"module.submodule" 将出现在输出中。但是,如果代码执行from module import non_module 之类的导入,则输出中只会出现"module"

【讨论】:

  • 非常感谢,它解决了我的问题。但是请注意,当从函数内完成导入时它会失败(这确实不是一个好习惯,但在我的项目代码中它已经完成了几次......)
  • @ezer1337 代码已更新;函数中的导入现在应该可以工作了。
猜你喜欢
  • 1970-01-01
  • 2015-10-06
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
相关资源
最近更新 更多