模块是一个包含所有定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用Python标准库的方法。模块让我们能够有逻辑地组织Python代码段,把相关的代码分配到一个模块里能让代码更好用、更易懂。
模块能定义函数、类和变量,模块里也能包含可执行的代码。例如:
#新建模块文件modle_1.py def p_func(arg): print('Hello',arg) return #新建主模块文件main.py from modle_1 import p_func #导入模块modle_1中的p_func函数 if__name__=="__main__": #判断是否为主程序执行口 p_func('Python')
运行程序,输出如下:
hello python
模块定义好后,可以使用import语句引入模块,语法格式为
import module1,[module2[,…moduleN]]
如果要引用模块math,则可以在文件最开始用import math引入。在调用math模块中的函数时,必须使用“模块名.函数名”。不管执行了多少次import,一个模块只会被导入一次,这样可以防止导入模块被重复执行。
from … import语句:
Python中的from语句可从模块中导入一个指定的部分到当前命名空间中,语法如下:
from modname import name1,name2,…,nameN from mod import func_1 #导入mod模块中的func_1函数
这个声明不会把整个mod模块导入到当前命名空间中,它只会将mod里的func_1单个引入到执行这个声明的模块的全局符号表。
from… import *
这样会把模块中的所有内容导入到当前命名空间,一般不建议使用,因为会消耗内存空间,也容易出现未预知的问题。
当导入一个模块后,Python解析器对模块位置的搜索顺序是:
当前目录→shell变量PYTHONPATH下的每个目录→Python模块路径目录。
模块的搜索路径存储在system模块的sys.path变量中,包括当前目录、Python路径和安装过程决定的默认目录。
import sys print(sys.path) ['','D:\\Anaconda3\\python36.zip','D:\\Anaconda3\\DLLs','D:\\Anaconda3\\lib','D:\\ Anaconda3','C:\\Users\\ASUS\\AppData\\Roaming\\Python\\Python36\\site-packages','D:\\ Anaconda3\\lib\\site-packages','D:\\Anaconda3\\lib\\site-packages\\Babel-2.5.0-py3.6. egg','D:\\Anaconda3\\lib\\site-packages\\win32','D:\\Anaconda3\\lib\\site-packages\\ win32\\lib','D:\\Anaconda3\\lib\\site-packages\\Pythonwin','D:\\Anaconda3\\lib\\site- packages\\IPython\\extensions','C:\\Users\\ASUS\\.ipython']
其中,空字符串表示当前工作目录。当安装第三方模块的时候,如果不是按照标准方式安装,为了能够引用这些模块,必须将这些模块的安装路径添加到sys.path中,添加方法如下:
(1)最简单的方法是在sys.path的某个目录下添加路径配置文件,最常见的就是在…/site-package/目录下,路径配置文件的扩展名为“.pth”,其中的每一行包含一个单独的路径,该路径会添加到sys.path列表中,“.pth”中的路径可以是绝对路径也可以是相对路径,如果是相对路径则是相对于包含“.pth”文件的路径而言的。
import sys print(sys.path) #默认搜索路径 [root@python site-packages]#vim/media/aa.py #在site-packages下新建配置文件system.pth,内容为需要添加的模块路径 [root@python site-packages]#cat system.pth /media #在/media目录下新建模块aa.py [root@python site-packages]#cat/media/aa.py def munit(x,y): print('sun:',x+y) return x+y ['', 'D:\\Anaconda3\\python36.zip', 'D:\\Anaconda3\\DLLs', 'D:\\Anaconda3\\lib', 'D:\\Anaconda3', 'C:\\Users\\ASUS\\AppData\\Roaming\\Python\\Python36\\site-packages', 'D:\\Anaconda3\\lib\\site-packages', 'D:\\Anaconda3\\lib\\site-packages\\Babel-2.5.0-py3.6.egg', 'D:\\Anaconda3\\lib\\site-packages\\win32', 'D:\\Anaconda3\\lib\\site-packages\\win32\\lib', 'D:\\Anaconda3\\lib\\site-packages\\Pythonwin', 'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\ASUS\\.ipython'] import aa #导入模块aa aa.munit(1,2) #执行模块中的函数 sun:3 3
(2)另一种方法是在Python标准库中修改site.py文件,并编辑sys.path。除非使用了-S开关选项,否则site.py在Python解释器加载时会自动被引入(执行),作用是加载site-packages中的包和模块到Python的sys.path里面。
import aa --------------------------------------------------------------------- ModuleNotFoundError Traceback(most recent call last) <ipython-input-18-510651a95b7a> in<module>() ---->1 import aa ModuleNotFoundError:No module named 'aa' import sys sys.path ['', 'D:\\Anaconda3\\python36.zip', 'D:\\Anaconda3\\DLLs', ... 'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\ASUS\\.ipython'] import sys sys.path.append("/media") #添加模块路径到搜索路径中 sys.path ['', 'D:\\Anaconda3\\python36.zip', 'D:\\Anaconda3\\DLLs', 'D:\\Anaconda3\\lib', ... 'C:\\Users\\ASUS\\.ipython', '/media'] import aa aa.munit(2,3) sun:5 5
(3)修改PYTHONPATH环境变量,一般不推荐使用此方法。
set PYTHONPATH=/usr/local/lib/python
一个模块被另一个程序第一次引入时,其主程序将运行。如果想在模块被引入时,模块中的某一程序块不执行,可以用__name__属性使该程序块仅在该模块自身运行时执行。例如:
if__name__== '__main__': print('程序自身在运行') else: print('我来自另一模块')
运行程序,输出如下:
程序自身在运行 import using_name
运行程序,输出如下:
我来自另一模块
由结果可看出,每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,否则是被引入。__name__与__main__底下是双下画线。
变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称(键)和相应的对象(值)的字典。一个Python表达式可以访问局部命名空间和全局命名空间里的变量。如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。每个函数都有自己的命名空间。类的方法的作用域规则和通常函数的一样。
Python会智能地猜测一个变量是局部的还是全局的,它假设任何在函数内赋值的变量都是局部的。因此,如果要给函数内的全局变量赋值,必须使用global语句。global VarName的表达式会告诉Python, VarName是一个全局变量,这样Python就不会在局部命名空间里寻找这个变量了。
例如,在全局命名空间里定义一个变量Money,再在函数内给变量Money赋值。Python会假定Money是一个局部变量,由于并没有在访问前声明一个局部变量Money,结果则会出现一个UnboundLocalError的错误。此时取消global语句的注释就能解决这个问题。
Money=2000 #定义全局变量 def addmoney(): #global Money Money=Money+1 #函数内不能直接调用全局变量,必须用global来声明全局变量 print(Money) 2000 addmoney() print(Money) UnboundLocalError Traceback(most recent call last) <ipython-input-24-a3819a35e2e7> in<module>() ----> 1 addmoney() UnboundLocalError:local variable 'Money'referenced before assignment
下面介绍几个与模块相关的函数。
dir()函数一个排好序的字符串列表,内容是一个模块里定义过的名字。返回的列表容纳了在一个模块里定义的所有模块、变量和函数。例如:
import fibo,sys dir(fibo) ['__name__','fib','fib2'] dir(sys) ['__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', ... 'version_info', 'warnoptions', 'winver']
如果没有给定参数,那么dir()函数会罗列出当前定义的所有名称。
a=[1,2,3,4,5] import fibo fib=fibo.fib dir() #得到一个当前模块中定义的属性列表 ['__builtins__','__name__','a','fib','fibo','sys'] a=5 #建立一个新的变量'a' dir() ['__builtins__','__doc__','__name__','a','sys'] del a #删除变量名a dir() ['__builtins__','__doc__','__name__','sys']
根据调用地方的不同,globals()和locals()函数可被用来返回全局和局部命名空间里的名字。如果在函数内部调用locals(),则返回的是所有能在该函数里访问的命名。如果在函数内部调用globals(),则返回的是所有在该函数里能访问的全局名字。两个函数的返回类型都是字典。所以能用keys()函数摘取名字。
当一个模块被导入到一个脚本,模块顶层部分的代码只会被执行一次。因此,如果需要重新执行模块里顶层部分的代码,则可以用reload()函数。该函数会重新导入之前导入过的模块。
包是一个分层次的文件目录结构,它定义了一个由模块、子包和子包下的子包等组成的Python的应用环境。
简单来说,包就是文件夹,但该文件夹下必须存在__init__.py文件,该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。
【例2-16】 Python中的包实例演示。
#首先在根目录下创建两个目录,分别创建模块aa,bb [root@python media1]#ls/media/ aa.py__pycache__ [root@python media1]#ls/media1/ bb.py__pycache__ #在aa和bb模块下创建函数: [root@python media1]#cat/media/aa.py def munit(x,y): print('sun:',x+y) return x+y [root@python media1]#cat/media1/bb.py def mule(x,y): return x * * y #调用模块 [root@python~]#cat init.py import sys sys.path.append("/media") from aa import munit print(sys.path) s=munit(3,4) print(s) [root@python~]#python3 init.py
运行程序,输出如下:
['', 'D:\\Anaconda3\\python36.zip', 'D:\\Anaconda3\\DLLs', 'D:\\Anaconda3\\lib', 'D:\\Anaconda3', 'C:\\Users\\ASUS\\AppData\\Roaming\\Python\\Python36\\site-packages', 'D:\\Anaconda3\\lib\\site-packages', 'D:\\Anaconda3\\lib\\site-packages\\Babel-2.5.0-py3.6.egg', 'D:\\Anaconda3\\lib\\site-packages\\win32', 'D:\\Anaconda3\\lib\\site-packages\\win32\\lib', 'D:\\Anaconda3\\lib\\site-packages\\Pythonwin', 'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\ASUS\\.ipython', '/media']