模块化是现代程序语言的一大特点,尤其是随着软件规模越来越大,按功能分块开发,便于多个开发人员相互协作,也便于后期维护。
Python通过import机制将各模块组织起来。
模块的形式:
模块是一个以.py结尾的文件,可以定义变量、方法与类;同时,在模块内可以import进其他模块,如果需要引用其他模块内的变量、方法或对象。
import的本质:
import某一模块,相当于在当前环境中把某块内的代码执行一遍,使得该模块定义的变量、方法可见。为防止名称冲突,引用时通过模块名.变量名(module.variable)的方式访问。如果在当前环境中还有同样名字的变量variable,它们俩之间没有任何关系,引用时要区分开。
例一:
#t1.py
import t2
print "a variable in t2 is %s" % t2.var_in_t2
print "now will call a function in t2"
print ">>>t2.func_in_t2"
t2.func_in_t2()
#t2.py
var_in_t2 = 0
def func_in_t2():
print "this is a function in t2.py"
print "execution of t2.py"
#执行import t1后的输出结果
execution of t2.py
a variable in t2 is 0
now will call a function in t2
>>>t2.func_in_t2
this is a function in t2.py
并且import具有层次性质,即在t1中import t2模块,在t1的上一级是不能访问到t2中的对象的。
>>> t2.var_in_t2
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
t2.var_in_t2
NameError: name 't2' is not defined
#在执行import t1后,在t1中import t2,所以t1中可以访问t2中的变量,但是在t1之外,例如,全局环境下试图访问t2.var_in_t2,报错。
从上例中可以看出在t1中建立了一个命名空间t2,通过这个命名空间,t1可以访问t2模块中定义的变量和函数。并且这个命名空间只对t1放开的。如果想在全局环境下使用t2中的对象,必须import t2.
from ... import ...
如果使用from xxx.py import xxx.varorfun,则有所不同,会在当前环境中建立和变量varorfun同名的对象,并且将xxx.py内的变量赋值给它们,这样在当前环境中直接访问该变量了,不需要加模块名。
package:
包一般是目录,内含python模块或者子目录,同时一般还包含一个__init__.py的python文件,在这个init文件中初始化首次import package时执行的模块。例如,
Package1/ __init__.py
Module1.py
Module2.py
Package2/ __init__.py
Module1.py
Module2.py
表示一个包Package1,它包含__init__py、Module1.py、Module2.py,同时包含子目录Package2及其模块。当需要导入包时,例如import Package1,就会执行Package1下的__init__.py文件。如果想在导入包是做些初始化的工作,例如导入其他的包等等,都可以在这里文件里写。其中有个list变量__all__,它包含当执行from Package1 import *时导入的包名,例如__all__ = ["Module1", "Module2"]。如果只想单独导入某个模块,可以这样:import Package1.Module1、import Package1.Package2.Module2。