【问题标题】:Hide external modules when importing a module (e.g. regarding code-completion)导入模块时隐藏外部模块(例如关于代码完成)
【发布时间】:2013-05-12 15:37:45
【问题描述】:

我在一个包(一种工具包)中有几个模块,我在我的项目中使用它们。结构如下:

the_toolkit:
    __init__.py
    basic_io.py
    simple_math.py
    matrix_kit.py
    ...

现在当我从包中导入模块后使用IPythonVIM 中的代码完成

from the_toolkit import matrix_kit

我得到了一堆 matrix_kit.py 导入的模块/函数(arraymathloglogginformat_exc 等),以及 matrix_kit 的实际函数定义。 我如何过滤掉其他所有内容,因为我对 matharraymatrix_kit 模块的代码完成不感兴趣?

__init__.py 是空的,正如许多 pythonistas 所建议的那样,还是这样做的方式?

【问题讨论】:

标签: python code-completion python-import


【解决方案1】:

我遇到了同样的问题,并通过在我的所有导入中添加前导下划线来解决它。它看起来并不出色,但它实现了你所追求的。

from __future__ import division as _division
import numpy as _np
import pandas as _pd

当您使用 from .. import * 导入模块时,只会导入不带下划线开头的内容。或者当您在 IPython 或 spyder 中使用制表符完成时。

【讨论】:

  • 这是我发现的唯一可行的解​​决方案。谢谢你。顺便说一句,您应该注意下划线被添加到模块内的导入中,稍后您将其作为包导入。现在有点混乱。
【解决方案2】:

我开始喜欢并使用这种方法。从您的项目结构开始,我们将隐藏matrix_kit 中您不想显示的所有内容。

the_toolkit:
    __init__.py
    basic_io.py
    simple_math.py
    matrix_kit.py
    ...

matrix_kit.py移动到同名包中,并在模块名称的开头加一个下划线:

the_toolkit:
    __init__.py
    basic_io.py
    simple_math.py
    matrix_kit:
        __init__.py
        _matrix_kit.py
    ...

现在在_matrix_kit.py 中添加一个全局变量__all__ = [...],列出您希望显示的所有函数/类/变量的名称。然后,将以下行添加到matrix_kit/__init__.py

from ._matrix_kit import *

它只会导入模块的__all__ 属性中列出的内容。然后,在像以前一样导入matrix_kit 时,您实际上将导入__init__.py 及其内容。

【讨论】:

  • 解决了困扰我一段时间的一个问题,谢谢!知道这是否是做这类事情的“典型”方式吗?
  • @Engineero 是的,我已经看到它在很多项目中使用过。
  • 我已经搜索了很多小时试图找到这样的答案。太感谢了。我真正喜欢这种方法的地方在于,使用制表符完成时 API 看起来是如何划分的。我真的很感激。
【解决方案3】:

我想出的另一种解决方案是在__init__ 文件中实现一个简短的API 类,该类可以利用__all__ 变量(可能已经为import * 目的而定义)。 __init__.py 中的类似内容:

import matrix_kit

class _matrix_kit_API:
    def __init__(self):
        for func in matrix_kit.__all__:
            setattr(self, func, eval(f"matrix_kit.{func}"))

matrix_kit = _matrix_kit_API()

【讨论】:

    【解决方案4】:

    你可能会从__all__获得一些里程

    【讨论】:

    • 您能说得更具体些吗?我应该在包中的所有模块中添加__all__ 并列出重要的功能吗? (进口蚂蚁,哈哈)
    • @second:您是否尝试在模块中定义__all__,然后在 IPython 中导入模块(不进行星号导入)?
    • 我没有使用*,我尝试在模块中添加__all__,但并没有解决问题。
    • @septi: 定义__all__ 是一个很好的做法,但它无助于解决您的完成问题 - 导入的名称仍然可以从模块的字典中访问,因此可以由完成者的代码。 IOW,问题在于您的自动完成器实现(不会过滤掉导入的名称),而不是 Python 本身。
    • __all__ 在这里不起作用,因为它用于指定在使用from * 语句时要导入哪些模块文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多