python module
Python 的标准安装包括了一组模块,称之为标准库(standard library)。前几篇blog中已经提到如何引用和使用第三方的模块,这次主要说明自定义模块在其它模块的调用,以及包括这些模块的工作方式。
在项目开发,程序员会考虑代码的可扩展性和代码的可重用性,使用模块的好处,就是考虑使用了代码的可重用性。
模块
任何Python程序都可以作为模块导入,例如:
编写一个hello.py文件,包名:com.easymorse
#!/usr/bin/python #-*- coding: utf-8 -*- #Filename: hello.py print 'Hello Jordy!'
程序保存的位置比较重要,假如保存在/home/ubuntu/目录中
编写using_hello.py文件,引用hello模块(这个文件与hello.py在同一个包目录下):
#!/usr/bin/python #-*- coding: utf-8 -*- #Filename: us_hello.py import hello
在引用hello模块时,using_hello程序会在引用时,首先执行hello.py文件,而且在加载时只执行一次调用。如果在此导入该模块就什么也不会发生了。
import hello
在导入模块时并不是要在导入时执行某些操作,他们主要用于定义 类、函数、变量等。(这些东西只需要定义一次,导入模块多次和导入一次的效果是一样的)
模块中定义函数:
比方在hello.py模块中定义一个函数
def sayhi(): print '执行sayhi方法'
在using_hello.py中导入hello模块 import hello ,这时,print ‘Hello Jordy!’ 会被执行,访问刚才定义的sayhi()函数,可以通过:
hello.sayhi()
我们可以通过同样的方法来使用任何在模块的全局作用域中定义的方法和变量。
模块中添加测试代码:
模块是用来定义类、函数、变量的,但有些时候,在模块中添加一些检查模块本身是否正常工作的测试代码是很有用的。例如:上述的hello模块
#!/usr/bin/python #-*- coding: utf-8 -*- #Filename: hello.py print 'Hello Jordy!' def sayhi(): print '执行sayhi方法' version = '0.1' #测试调用 sayhi()
这样在using_hello模块导入hello模块时,会自身调用sayhi()函数,来检测这个函数的正确性。
但这同时会造成一个问题就是在导入hello模块时,hello模块本身会调用sayhi()函数,using_hello模块中的
hello.sayhi()这句话又会执行sayhi()函数。为了避免这种情况的发生,需要“告知”模块本身是作为程序运行还是导入其他程序,这时需要使用__name__变量:
通过上图可以看出,变量__name__的值是’__main__’,而在导入的模块中,这个值就被设定为模块的名字,因此,为了让模块的测试代码更好的使用,可以将其放置在if语句中,例如:
#!/usr/bin/python
#-*- coding: utf-8 -*-
#Filename: hello.py
print ‘Hello Jordy!’
def sayhi():
print ‘执行sayhi方法’
version = ’0.1′
#测试调用
def test():
sayhi()
if __name__ == ‘__main__’:
test()
这样在hello.py在作为程序执行时,sayhi()函数会被执行,而作为模块导入时,它的行为就会像普通模块一样,只有在调用sayhi()函数时,才会执行,而不是在模块被导入时就会执行。
上述两个文件都是在同一个包中列举的例子,那么当一个模块在一个包(com.easymorse)中,另一个模块在另一个包中(com.witmob),如何导入呢?
其实,我们知道包就是模块所在的目录,为了能让Python将这个目录作为包对待,它必须包含一个命名为__init__.py的文件(这个文件在我们创建包时,eclipse会自动帮我们创建这个命名的一个文件),如果将这个文件作为一个模块导入的话,文件的内容就是包的内容。
比如:在com.easymorse包中的__init__.py文件中有一个属性:
PI = 3.14
在com.witmob包中导入这个模块:
import com.easymorse print com.easymorse.PI
如果在com.witmob包中导入hello.py这个模块,有两种方式:
import com.easymorse.hello from com.easymorse import hello
通过这两种方式,都可以访问hello模块中的方法、属性,它们区别在于:
第一种方式需要通过全名com.easymorse.hello.sayhi()来使用;
第二种方式可以通过短名hello.sayhi()来使用;