Python中所谓的模块就是一个Python文件,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。模块由代码、函数或类组成。编程中使用模块不仅可以提高代码的可维护性,还可以提高代码可复用性。通过引用模块,每次编程不用都从0开始,引用模块的类型可以是Python内置的模块,也可以是第三方的模块。本文主要介绍内容包括:
(1)模块的定义。
(2)模块的查找路径和使用方法。
(3)模块的基本属性。
模块的创建
模块把一组相关的函数或代码组织到一个文件中,一个文件就是一个模块。模块由代码、函数或类组成。创建一个名为myModule.py的文件,就表示定义了一个名为myModule的模块。假设myModule.py内容如下:
def func():
print "myModule.func()"
class MyClass:
def myFunc(self):
print "myModule.MyClass.myFunc()"
在myModule模块中定义了一个函数func()和一个类MyClass。我们在myModule.py所在的目录下继续创建一个call_myModule.py的文件。在该文件中调用myModule模块的函数和类。call_myModule.py文件内容如下:
import myModule
myModule.func()
myClass = myModule.MyClass()
myClass.myFunc()
输出结果如下:
myModule.func()
myModule.Myclass.myFunc()
通过输出结果,我们可以知道在call_myModule程序中成功调用了myModule模块的func()函数和MyClass类中的myFunc()方法。到这里,我们就学会了模块创建和调用的基本用法。但回顾这个例子,在模块定义和使用时我们提前做了几个约束:
(1)调用程序call_myModule.py被要求与被调用的myModule模块在一个文件目录下。如果不在一个目录下会有什么问题?如何处理?
(2)导入模块使用import语句。除了import myModule语句,还有其他形式的语句可以用?
(3)myModule模块不存在调用func()和MyClass.myFunc()语句。如果存在,调用该模块的程序会出现重复打印吗?如何处理?
上述3个问题,问题(1)与Python模块查找路径有关,问题(2)与模块导入的方法有关,问题(3)与模块的属性有关,下面开始分别介绍。
Python查找模块路径
当Python导入一个模块时,Python首先查找当前路径,然后查找lib目录、site-packages目录(安装目录Libsite-packages)和环境变量PYTHONPATH设置的目录。简单的说,被调用的模块(包括自定义模块)可以放在和调用程序的文件在同一个层级目录下,或者放在sys.path所列出的目录下。sys.path的目录通常如下所示:
>>> import sys
>>> sys.path
['', 'C:\WINDOWS\SYSTEM32\python27.zip', 'c:\Python27\DLLs', 'c:\Python27\lib', 'c:\Python27\lib\plat-win', 'c:\Python27\lib\lib-tk', 'c:\Python27', 'c:\Python27\lib\site-packages', 'c:\Python27\lib\site-packages\win32', 'c:\Python27\lib\site-packages\win32\lib', 'c:\Python27\lib\site-packages\Pythonwin']
我们重新看上述的例子,假设myModule.py文件在D: emp目录下,与call_myModule程序不在同一个层级目录下。那么我们可以将D: emp目录添加到sys.path目录,实例如下:
import sys,
sys.path.append('D:\temp')
import myModule
myModule.func()
myClass = myModule.MyClass()
myClass.myFunc()
输出结果如下:
myModule.func()
myModule.Myclass.myFunc()
因此,如果在调试程序过程中出现ImportError: No module named myModule错误时,可以通过sys.path语句下的路径查找下是否存在提示的不存在的模块。
模块的导入方法
在使用一个模块的函数或类之前,首先要导入模块。模块的导入使用import语句格式如下:
import 模块名
这条语句可以直接导入一个模块。调用模块的函数或类时,需要以模块名作为前缀,使用格式如下所示:
模块名.函数名()
import语句的用法在上述例子中已经实践共了。但是如果不想在程序中使用前缀符,可以使用from...import...语句导入,from...import...语句导入主要有3种形式:
(1)导入模块中指定的函数或类
from 模块名 import 函数名
修改上述call_myModule.py的程序,代码如下:
import sys
sys.path.append('D:\temp')
from myModule import func, MyClass
func()
myClass = MyClass()
myClass.myFunc()
(2)导入模块中所有的函数和类
import sys
sys.path.append('D:\temp')
from myModule import *
func()
myClass = MyClass()
myClass.myFunc()
(3)导入模块中指定的函数和类,并修改为指定名称
import sys
sys.path.append('D:\temp')
from myModule import func as myModule_func
myModule_func()
模块的属性
模块有一些内置属性,用于完成特定的任务,如__name__、__doc__。每个模块都有一个名称,例如,__name__用于判断当前模块是否是程序的入口,如果当前程序正在被使用,__name__的值为"__main__"。通常给每个模块都添加一个条件语句,用于单独测试该模块功能。修改myModule.py,代码如下:
def func():
print "myModule.func()"
class MyClass:
def myFunc(self):
print "myModule.Myclass.myFunc()"
if __name__ == '__main__':
print "myModule execute as main program"
else:
print "myModule called by other program"
执行call_myModule.py调用程序,获取结果如下:
myModule called by other program
myModule.func()
myModule.Myclass.myFunc()
通过输出结果可以知道,myModule模块被call_myModule.py程序调用时if __name__ == '__main__'条件下的语句块不会被执行。现在知道问题(3)怎么解决了吗?将主程序放在if __name__ == '__main__'条件中的语句块就可以了。
小结
学完本文,你知道如何调用自定义的模块了吗?自己动手写一个模块并尝试导入吧~~