首页 文章

当本地模块屏蔽外部模块导入的标准库模块时,如何导入外部模块?

提问于
浏览
2

我有一个名为 tokenize.py 的本地模块,它掩盖了一个同名的标准库模块 . 我只是在尝试导入外部模块(sklearn.linear_model)时发现了这一点,而外部模块又是 import tokenize 并期望获得标准库模块,而是获取我的本地模块 .

这与How to access a standard-library module in Python when there is a local module with the same name?有关,但设置不同,因为应用上述解决方案需要修改外部模块 .

一个选项是重命名本地 tokenize.py ,但我不希望这样做,因为"tokenize"最能表达模块的作用 .

为了说明问题,这里是模块结构的草图:

\my_module
      \__init__.py
      \tokenize.py
      \use_tokenize.py

在use_tokenize.py中,有以下导入:

import sklearn.linear_model

调用 python my_module/use_tokenize.py 时会导致以下错误:

Traceback (most recent call last):
  File "use_tokenize.py", line 1, in <module>
    import sklearn.linear_model
  <...>
  File "<EDITED>/lib/python2.7/site-packages/sklearn/externals/joblib/format_stack.py", line 35, in <module>
    generate_tokens = tokenize.tokenize
AttributeError: 'module' object has no attribute 'tokenize'

导入外部模块时有没有办法抑制本地模块?

编辑:添加python2.7作为标记,因为解决方案因Python版本而异

2 回答

  • 3

    问题不在于模块名称,而是在运行类似于脚本的模块 . 当Python运行脚本时,它会将脚本的包含目录添加为 sys.path 中的第一个元素,因此从任何地方进行的所有模块查找都将首先搜索该目录 .

    要避免这种情况,请让Python将其作为模块执行:

    python -m my_module.use_tokenize
    

    或者,当然,您可以将可执行脚本保留在模块层次结构之外 .

  • 0

    解释器搜索模块的路径列在 sys.path 中 . 为防止第三方模块在导入时看到本地模块,我们从路径中删除 . . 这可以通过以下方式实现:

    import sys
    sys.path = sys.path[1:]
    import sklearn.linear_model #using the original example.
    

    但是,如果已导入本地 tokenize ,这将无效,并且即使我们恢复旧的 sys.path ,它也将阻止导入本地 tokenize ,如下所示:

    import sys
    old_path = sys.path
    sys.path = sys.path[1:]
    import sklearn.linear_model #using the original example.
    sys.path = old_path
    

    这是因为Python解释器维护导入模块的内部映射,以便从该映射实现对同一模块的后续请求 . 这个映射对于解释器是全局的,因此 import tokenize 从运行它的任何代码返回相同的模块 - 这正是我们试图改变的行为 . 为此,我们必须改变这种映射 . 最简单的方法是从 sys.modules 删除相关条目 .

    import sys
    old_path = sys.path
    sys.path = sys.path[1:]
    import sklearn.linear_model #using the original example.
    sys.path = old_path
    del sys.modules['tokenize'] #get of the mapping to the standard library tokenize
    import tokenize #cause our local tokenize to be imported
    

相关问题