python - 区分 python 同级导入与导入函数/类

标签 python python-import python-importlib

我正在编写一个 pylint 检查器,我需要区分包的同级导入和函数或类的导入。

同级导入示例:

from . import sibling_package

函数导入示例:

from numpy import array

我想标记后一个示例,而我想允许前一个示例,因此我需要能够区分两者之间的区别。

我目前正在使用:

modspec = importlib.util.find_spec('numpy', 'array')

这会返回一个ModuleSpec,但我不清楚如何实现将导入array识别为模块与函数/类的目标。在本例中,它是一个函数导入,因此应该被标记。

最佳答案

这不是您可以仅从导入行轻松检测到的东西。 Python 是高度动态的,直到运行时你才能知道导入解析为什么类型的对象。模块规范无法告诉您此信息,因为模块上的属性可以解析为任何内容(包括另一个模块)。

我可以看到的替代方案是:

  • 进行实际导入,然后测试对象类型。

    这并非没有风险,进口可能有副作用。导入模块包括执行顶层语句。这些副作用可能很轻微,例如在不满足依赖项时将一个对象替换为另一个对象( try: from itertools import zip_longestexcept ImportError: from itertools import izip_longest as ziplongest 是一个简单的 Python 2 与 Python 3 依赖项检查),但导入可能会导致文件系统更改!

    导入也会减慢检查速度。导入类似 numpy 的模块或pandas可以引入大量附加模块。您通常希望保持 linting 快速,否则开发人员往往不会费心并完全跳过 linting。

  • 保留已知模块的列表。对于您了解的那些模块,如果它们从模块导入名称而不是模块本身,请提示。这速度很快,并且可以捕获大多数常见情况。您可以使用从正在检查的模块周围的文件系统中收集到的内容来扩充列表。换句话说,目标是足够快且足够好,并接受新导入的一些失误。

  • 仅在直接调用导入的名称时才会提示。注册所有导入的名称,如果 AST 包含 Call该名称的节点那么您就知道他们导入了函数或类。 from foo import bar ,然后是 spam = bar('baz')是一个明确的指标 bar不是一个模块。

关于python - 区分 python 同级导入与导入函数/类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52064613/

相关文章:

python - 将一个文件中的所有对象添加到另一个文件中的列表

python - 在 python 中导入模块的最 pythonic 方法是什么

python - ModuleNotFoundError 在从 importlib 导入的模块上使用 "classic"导入

python - 从 C++ 到 Python 的 OpenCV absdiff 等价物

处理导入错误的 Pythonic 方式

javascript - 403(禁止)

python - 更改目录后找不到模块

python - 从 django.utils.importlib 导入 import_module 导入错误 : No module named importlib

python - Tensorflow 在使用队列的 sess.run 调用上卡住

python - 如何将多个数据框写入一张 Excel 工作表?