1.python中的包
包将有联系的模块组织在一起,有效避免模块名称冲突问题,让应用组织结构更加清晰
假定我们的包的例子有如下的目录结构:
Phone/ __init__.py common_util.py Voicedta/ __init__.py Pots.py Isdn.py Fax/ __init__.py G3.py Mobile/ __init__.py Analog.py igital.py Pager/ __init__.py Numeric.py
Phone 是最顶层的包,Voicedta 等是它的子包。 我们可以这样导入子包:
import Phone.Mobile.Analog Phone.Mobile.Analog.dial()
你也可使用 from-import 实现不同需求的导入
第一种方法是只导入顶层的子包,然后使用属性/点操作符向下引用子包树:
from Phone import Mobile Mobile.Analog.dial('555-1212')
此外,我们可以还引用更多的子包:
from Phone.Mobile import Analog Analog.dial('555-1212')
事实上,你可以一直沿子包的树状结构导入:
from Phone.Mobile.Analog import dial dial('555-1212')
在我们上边的目录结构中,我们可以发现很多的 __init__.py
文件。这些是初始化模块,from-import 语句导入子包时需要用到它。 如果没有用到,他们可以是空文件。
包同样支持 from-import all 语句:
from package.module import *
然而,这样的语句会导入哪些文件取决于操作系统的文件系统。所以我们在__init__.py
中加入 __all__
变量。该变量包含执行这样的语句时应该导入的模块的名字。它由一个模块名字符串列表组成.。
2. __all__
Python的moudle是很重要的一个概念,moudle里一般都会有一个__init__.py
文件。有的__init__.py
中是空白,有的却会有__all__
参数。
如果其他页面import 的时候如果__init__.py
是空白的,可以直接import到moudle的所有函数。而如果__init__.py
中定义了__all__
,则import 的时候只会导入__all__
部分定义的内容。
例如,我们可以这样组织一个package:
package1/ __init__.py subPack1/ __init__.py module_11.py module_12.py module_13.py subPack2/ __init__.py module_21.py module_22.py
__init__.py
可以为空,只要它存在,就表明此目录应被作为一个package处理。当然,__init__.py
中也可以设置相应的内容
现在我们在module_11.py中定义一个函数:
def funA(): print "funcA in module_11"
在顶层目录(也就是package1所在的目录,当然也参考上面的介绍,将package1放在解释器能够搜索到的地方)运行python:
>>>from package1.subPack1.module_11 import funcA >>>funcA() funcA in module_11
这样,我们就按照package的层次关系,正确调用了module_11中的函数。
细心的同学会发现,有时在import语句中会出现通配符*,导入某个module中的所有元素,这是怎么实现的呢?
答案就在__init__.py
中。我们在subPack1的__init__.py
文件中写
__all__ = ['module_13', 'module_12']
然后进入python
>>>from package1.subPack1 import * >>>module_11.funcA() Traceback (most recent call last): File "", line 1, in ImportError: No module named module_11
也就是说,以*导入时,package内的module是受__init__.py
限制的。