我有以下包结构:
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
但当pandas
形成dir(myzip)
时,它仍会显示main.py
。
查看from sklearn import cluster
他们设法实现这一目标,而不显示他们拥有的所有numpy
次导入,例如在cluster/k_means_.py
答案 0 :(得分:1)
如果在moduleB
的模块级导入moduleA
,则moduleB
是moduleA
命名空间的一部分。
隐藏它的一种方法是使用别名导入它:
import pandas as _hidden_pandas
然后它会显示为_hidden_pandas
,在某种程度上隐藏它。
制表完成至少找不到它。
答案 1 :(得分: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 *
的人可能会遇到名称save
或load
的冲突。在涉及星型导入名称冲突时,没有必要特别担心导入的模块名称。
另外,值得注意的是,许多广泛使用的库以这种方式暴露了他们自己的导入,并且它不被认为是一个问题。熊猫本身就是一个例子:
>>> import pandas
>>> pandas.np
<module 'numpy' from '...'>
。 。 。如果您认为这是一个没问题的话,那么你就是一个好伙伴。
答案 2 :(得分:0)
将子模块嵌套到一个文件夹中,只导入__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)
会列出load
,save
和myzip
,而不会隐藏pandas
myzip.myzip.<TAB>
{1}}。
还没弄明白sklearn
如何隐藏他们的第三方模块。