【问题标题】:Import specific names only仅导入特定名称
【发布时间】:2018-02-17 12:56:10
【问题描述】:

我的包结构如下:

analysis/
         __init__.py
         main.py
         utils/
               __init__.py
               myzip.py 

myzip.py 包含以下内容:

import pandas
def save():
    ...
def load():
    ...

在我的main.py 脚本中我这样做:

from utils import myzip

当我输入myzip.<TAB> 或输入dir(myzip) 时,导入的pandas 也会出现。 我可以避免在子模块中显示pandas 吗? 是否有导入第三方模块的最佳做法?


我尝试将以下内容添加到analysis/utils/__init__.py

from utils.myzip import save, load

但当我 dir(myzip) 形成 main.py 时,它仍然显示 pandas

看着from sklearn import cluster,他们设法实现了这一点,但没有显示他们拥有的所有numpy 导入,例如在cluster/k_means_.py

【问题讨论】:

  • 如果您的保存和加载功能依赖于 pandas,那么您的程序需要能够访问 pandas 而不考虑它尝试执行保存和加载功能的位置是否有意义?跨度>
  • dir(utils) 在哪里被执行?您的示例代码都没有导入 utils
  • @martineau 感谢您指出这一点,这是一个错字。如果我确实导入 utils 它,那么我会得到 saveloadmyzip 作为建议。这接近我嵌套到文件夹的解决方案,缺点是我想使用myzip.save() 而不是utils.save()
  • 您的 sklearn 示例不平行。您正在导入cluster,而不是k_means_,因此您只能在cluster 中看到名称,而cluster 不会从k_means_ 导入np。如果您执行from sklearn.cluster import k_means_,您将看到k_means_.np 确实可用。您可以使用与您发布的解决方案类似的解决方案轻松实现这一目标。
  • 我认为有几个问题与此重复,例如thisthis。请澄清您要问的问题。

标签: python import module package


【解决方案1】:

this question 中所述,您可以导入具有以下划线开头的别名的模块(例如,import pandas as _pandas)。该名称仍可用作 myzip._pandas,但 IPython 制表符完成不会自动完成它(除非您先明确键入下划线)。此外,如果您执行from myzip import *,它将不会被导入,尽管您不应该这样做。

然而,正如this other question 中提到的,更好的“解决方案”就是不要担心它。如果有人做了import myzip,那么他们能够访问myzip.pandas 并没有什么坏处;反正他们也不能自己导入pandas。此外,在这种情况下不存在名称冲突的风险,因为 pandas 在您的模块下命名空间。可能出现名称冲突的唯一方法是,如果您的模块本身将名称 pandas 用于两个不同的事物(例如,除了导入的模块之外,还定义了一个名为 pandas 的全局变量);但这是模块内部的问题,无论 pandas 是否可从外部访问。

如果某人有自己的变量pandas,然后使用from myzip import *,则可能会出现名称冲突,但正是出于这个原因,不鼓励星号导入,并且导入模块的名称在这方面与其他名称没有什么不同.例如,使用from myzip import * 的人可能会面临与名称saveload 的冲突。当涉及到星形导入名称冲突时,专门担心导入的模块名称是没有用的。

另外,值得注意的是,许多广泛使用的库都以这种方式公开自己的导入,这不被视为问题。 Pandas 本身就是一个例子:

>>> import pandas
>>> pandas.np
<module 'numpy' from '...'>

。 . .因此,如果您认为这不是问题,那么您就是一个很好的公司。

【讨论】:

    【解决方案2】:

    部分解决方案

    将子模块嵌套到一个文件夹中,只导入__init__.py中必要的方法,即:

    analysis/
             __init__.py
             main.py
             utils/
                   __init__.py
    -->            myzip/
                         __init__.py
                         myzip.py
    

    myzip/__init__.py 的位置:

    from .myzip import load, save

    然后在from utils import myzip 之后,dir(myzip) 将列出loadsavemyzip,但不会列出隐藏在myzip.myzip.&lt;TAB&gt; 中的pandas

    还没弄清楚sklearn是如何隐藏他们的第三方模块的。

    【讨论】:

      【解决方案3】:

      如果在moduleA 的模块级别导入moduleB,则moduleBmoduleA 命名空间的一部分。

      然而,隐藏它的一种方法是使用别名导入它:

      import pandas as _hidden_pandas
      

      然后它会显示为_hidden_pandas,在某种程度上隐藏它。 tab-completion 至少不会找到它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-01
        • 2018-01-25
        • 1970-01-01
        • 2016-09-02
        • 2022-06-25
        • 2017-12-03
        相关资源
        最近更新 更多