2012-05-24 36 views
2

为什么我要导入所有的子包如果我想要使用它们?
我将用一个例子解释一下:Python没有看到我的子包

In [1]: import cime 

In [2]: cime.runners 
--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
/home/miki/testit/<ipython-input-2-35e09c66121a> in <module>() 
----> 1 cime.runners 

AttributeError: 'module' object has no attribute 'runners' 

In [3]: import cime.runners 

In [4]: cime.runners 
Out[4]: <module 'cime.runners' from '/home/miki/testit/venv/lib/python2.7/site-packages/cime/runners/__init__.pyc'> 

正如你可以看到它是一个普通的Python包:

In [5]: cime.__file__ 
Out[5]: '/home/miki/testit/venv/lib/python2.7/site-packages/cime/__init__.pyc' 

In [6]: ls /home/miki/testit/venv/lib/python2.7/site-packages/cime 
download.py __init__.py log.py runners/ run.pyc utils.pyc 
download.pyc __init__.pyc log.pyc run.py utils.py 

但这不带内置模块发生。为什么?

In [7]: import os # instead of import os.path 

In [8]: os.path 
Out[8]: <module 'posixpath' from '/home/miki/testit/venv/lib/python2.7/posixpath.pyc'> 

感谢,
魔方

附:我在一个virtualenv里面,但我不知道这是否重要。

回答

2

这是由cime(不管是什么)设计决定的开发人员。一个包不会奇迹般地导入所有的子包。这是一件好事,因为否则像SciPy这样的大型软件包会永久导入(就像NLTK一样)。

一些包,如os.path,NumPy和NLTK将导入子模块,但他们明确这样做。如果您希望在您自己的模块中发生这种情况,请执行以下操作:

# __init__.py 
import .submodule 
+0

谢谢您的明确和快速回复! – rubik

+0

我会说:'os.path'是一个例外,而不是一个规则。 'import a'并不意味着在Python中导入a.b或导入a.c'。 – jfs

+1

是的,我现在看os.py源代码,它确实显式导入模块。 http://hg.python.org/cpython/file/290d970c011d/Lib/os.py – rubik

1

os.path是与实现细节相关的异常。 Python通常会保守做多少工作,所以它只会导入你真正需要的模块。由于os.path的实际执行依赖于您的操作系统,因此python会计算出您需要的实现,并在python启动时将其作为os.path导入。

你可以得到一个非常类似的效果,如果这就是你想要的东西,通过增加一定的附加进口的cime/__init__.py

from cime import runners 

等。