2013-11-14 128 views
2

我有一个模块:模块揭露导入包

test 
    __init__.py 

__init__.py我有一行:

import numpy as np 

我希望在整个包中使用numpy的(模块和子模块)我要创建。

问题是,不知何故numpy越来越暴露。如果我运行IPython并做

import test 

将会有一个test.np可访问。

我看了很多github上的软件包,他们经常导入很多主要的__init__.py(sys,division等),但是当我在IPython中导入这些软件包时,没有任何外部模块被暴露。

他们的表现有什么不同?

+0

既然您正在查看这些软件包的来源,或许您可以看到他们在做什么来阻止它们。 – martineau

+0

是的,看着这个,但到目前为止还没有想法 – dreamwalker

回答

2

你可以定义一个全局命名__all__,设置名称列表或元组,来限制进口和一般将列出文档的工具:

__all__ = ['function1', 'ClassName2'] 

__all__名称限制什么from test import *会导入,并且还被文档工具用来限制为给定模块列出的公共API。

import statement文档:

由模块定义的确定公共名通过检查模块的名为__all__变量的命名空间;如果定义了它,它必须是由该模块定义或导入的名称的字符串序列。 __all__中给出的名称都被认为是公开的,并且必须存在。如果未定义__all__,则公用名称集合将包含模块名称空间中的所有名称,该名称不以下划线字符开头('_')。 __all__应该包含整个公共API。它旨在避免意外导出不属于API的项目(例如在模块中导入和使用的库模块)。

您检查的__init__模块几乎肯定会定义__all__序列。

您还可以再从你的模块删除名,只要你的功能并不需要访问后的全局名称:

del sys 

IPython的自动完成,否则使用所有名不带启动下划线;自动完成忽略__all__列表,但会忽略像_sys这样的名称。

numpy.__init__ module本身再次从全局命名空间中删除名称(1.8.0之前的版本):

if __NUMPY_SETUP__: 
    import sys as _sys 
    _sys.stderr.write('Running from numpy source directory.\n') 
    del _sys 

但这里sys绑定为_sys和IPython中会忽略即使在未将其删除该名称。 numpy也在该模块中建立一个__all__列表。

numpy版本1.8.0和更新的版本中,import sys语句被添加到该文件中,并且IPython将其提供给自动完成,因为它仍然是全局命名空间的一部分。

+0

使用'__all__'而不写'np'不会使'test.np'无法访问。 – martineau

+0

@martineau:不,但*不是问题*。 IPython显示了自动完成目标,而OP在想,为什么有些项目似乎导入了各种库,但IPython没有列出它们。 –

+0

我测试了这个,即使我有'__all__' = []我仍然可以在IPython中看到我在'__init __。py'中导入的所有东西。无论导入语句是否为导入numpy或导入numpy为np,导入sys等 – dreamwalker

-1

你必须确保你只是以某种方式将它导入本地命名空间。

+0

虽然这可以通过将它导入到每个使用它的模块函数来完成,但除了繁琐以外,它也是低效的。 – martineau