《Python语言程序设计》 —3.3 模块
3.3 模块
如前面介绍,Python提供了交互式和脚本式两种运行方式。当要执行的代码比较长且需要重复使用时,我们通常将代码放在扩展名为.py的Python脚本文件中。当我们要编写一个规模比较大的程序时,如果将所有代码都放在一个脚本文件中,则不方便维护和多人协同开发。另外,对于可以在多个程序中重用的功能,也最好将其放在单独的脚本文件中,以方便多个程序通过引用该脚本文件来共享这些功能。此时,我们需要按照代码功能的不同,将代码分门别类地放在不同的脚本文件中,这些脚本文件称为模块(module)。
当要使用一个模块中的某些功能时,我们可以通过import方式导入该模块。例如,假设模块A中定义了一些变量和函数,如果希望在模块B中使用它们,则可以在模块B中通过import将模块A导入,此时在模块B中就可以使用这些变量并调用模块A的所有函数。
3.3.1 import
使用import语句导入模块的语法如下:
import module1
import module2
…
import moduleN
也可以在一行内导入多个模块:
import module1, module2, ..., moduleN
下面通过一个具体的例子说明模块使用的方法。首先,我们定义一个名字为fibo.py的脚本文件,其中包括PrintFib和GetFib两个函数的定义,参见代码清单3-11。
代码清单3-11 fibo.py脚本文件
1 def PrintFib(n): #定义函数PrintFib,输出斐波那契数列的前n项
2 a, b = 1, 1 #将a和b都赋为1
3 for i in range(1,n+1): #i的取值依次为1,2,…,n
4 print(a, end=' ') #输出斐波那契数列的第i项
5 a, b = b, a+b #更新斐波那契数列第i+1项的值,并计算第i+2项的值
6 print() #输出一个换行
7 def GetFib(n): #定义函数GetFib,返回斐波那契数列的前n项
8 fib=[] #定义一个空列表fib
9 a, b = 1, 1 #将a和b都赋为1
10 for i in range(1,n+1): #i的取值依次为1,2,…,n
11 fib.append(a) #将斐波那契数列的第i项存入列表fib中
12 a, b = b, a+b #更新斐波那契数列第i+1项的值,并计算第i+2项的值
13 return fib #将列表fib返回
14 PrintFib(10) #调用PrintFib输出斐波那契数列前10项
15 ls=GetFib(10) #调用GetFib函数获取斐波那契数列前10项组成的列表
16 print(ls) #输出列表ls中的元素
程序执行完毕后,将在屏幕上输出如下结果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
提示 斐波那契数列(Fibonacci sequence)又称黄金分割数列,因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。斐波那契数列前两项的值都为1,后面每一项的值等于其前两项的和,即F(1)=F(2)=1,F(n)=F(n-1)+F(n-2)(n>2)。
下面我们再编写一个名为testfibo.py的脚本文件,参见代码清单3-12。
代码清单3-12 testfibo.py脚本文件
1 import fibo #导入fibo模块
2 fibo.PrintFib(5) #调用fibo模块中的PrintFib函数,输出斐波那契数列前5项
3 ls=fibo.GetFib(5) #调用fibo模块中的GetFib函数,得到斐波那契数列前5项的列表
4 print(ls) #输出ls中保存的斐波那契数列前5项
程序执行完毕后,将在屏幕上输出如下结果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
1 1 2 3 5
[1, 1, 2, 3, 5]
提示 导入模块后,如果要使用该模块中定义的标识符,则需要通过“模块名.标识符名”的方式。
从程序的输出结果可以看到,虽然我们只在testfibo.py中输出了斐波那契数列的前5项,但当执行import fibo时,也执行了fibo.py中第14~16行代码,所以会同时输出斐波那契数列的前10项数据。下面我们考虑一下如何避免这个问题,使得一个脚本文件单独运行时就执行这些语句;而作为模块导入时,就不执行这些语句。要实现这个功能,需要用到每个模块中都有的一个全部变量__name__。__name__的作用是获取当前模块的名称,如果当前模块是单独执行的,则其__name__的值就是__main__;否则,如果是作为模块导入,则其__name__的值就是模块的名字。例如,对于代码清单3-13和代码清单3-14:
代码清单3-13 module.py脚本文件
1 print(__name__) #输出全局变量__name__的值
代码清单3-14 testmodule.py脚本文件
1 import module #导入module模块
当执行module.py时,会在屏幕上输出__main__;而当执行testmodule.py时,则会在屏幕上输出module。也就是说,module.py单独运行和作为模块导入时,其__name__的值是不同的。因此,我们可以将代码清单3-11加以修改,参见代码清单3-15中加粗部分。
代码清单3-15 修改后的fibo.py脚本文件
1 def PrintFib(n): #定义函数PrintFib,输出斐波那契数列的前n项
2 a, b = 1, 1 #将a和b都赋为1
3 for i in range(1,n+1): #i的取值依次为1,2,…,n
4 print(a, end=' ') #输出斐波那契数列的第i项
5 a, b = b, a+b #更新斐波那契数列第i+1项的值,并计算第i+2项的值
6 print() #输出一个换行
7 def GetFib(n): #定义函数GetFib,返回斐波那契数列的前n项
8 fib=[] #定义一个空列表fib
9 a, b = 1, 1 #将a和b都赋为1
10 for i in range(1,n+1): #i的取值依次为1,2,…,n
11 fib.append(a) #将斐波那契数列的第i项存入列表fib中
12 a, b = b, a+b #更新斐波那契数列第i+1项的值,并计算第i+2项的值
13 return fib #将列表fib返回
14 if __name__=='__main__': #只有单独执行fibo.py时该条件才成立
15 PrintFib(10) #调用PrintFib输出斐波那契数列前10项
16 ls=GetFib(10) #调用GetFib函数获取斐波那契数列前10项组成的列表
17 print(ls) #输出列表ls中的元素
此时,当执行fibo.py时,将在屏幕上输出如下结果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
当执行testfibo.py时,将在屏幕上输出如下结果:
1 1 2 3 5
[1, 1, 2, 3, 5]
即修改后的fibo.py中的第15~17行代码因条件不成立而没有执行。
除了可以导入自己编写的模块外,也可以直接导入系统提供的模块,使用其中的功能。例如,我们可以通过sys模块获取运行Python脚本时传入的参数,如代码清单3-16所示。
代码清单3-16 修改后的testfibo.py脚本文件
1 import fibo #导入fibo模块
2 import sys #导入系统提供的sys模块
3 n=int(sys.argv[1]) #通过sys模块的argv获取执行脚本时传入的参数
4 fibo.PrintFib(n) #调用fibo模块中的PrintFib函数,输出斐波那契数列前n项
5 ls=fibo.GetFib(n) #调用fibo模块中的GetFib函数,得到斐波那契数列前n项的列表
6 print(ls) #输出ls中保存的斐波那契数列前n项
在系统控制台下,如果执行python testfibo.py 5,则会输出如下结果:
1 1 2 3 5
[1, 1, 2, 3, 5]
如果执行python testfibo.py 10,则会输出如下结果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
提示 读者可尝试在一个Python脚本文件中导入sys模块后,执行print(sys.argv),即可看到输出的一个列表,其中第一个元素是脚本文件名,后面的元素是运行脚本文件时传入的参数。
- 点赞
- 收藏
- 关注作者
评论(0)