模块的创建
由python语句组成的文本文件并且以.py结尾,都能自动被认为是Python模块。在文件顶层定义的变量都可以成为模块的属性,可以通过导入供其他模块使用。
模块名在Python程序中会变成变量名,所以事实上,需要导入的模块名都需要遵守Python变量名的命名规则。当有一个模块被导入时,Python会把内部模块名映射到外部文件名,即在编程时,模块名对应到一个.py的文件名。
模块的使用
Python可以使用import 和 from语句来使用模块。区别在于import语句是将整个模块全部导入,而from语句是获取(或者说复制)模块中的变量名
- 通过import语句导入的是整个模块,如果要使用的模块中的变量,就需要指明模块的命名空间.。
- 通过from语句导入模块中变量时,就相当于将属性复制到本模块,新建了一个变量名一样。
- 可以使用from [module] import * 来复制模块中所有顶层的变量。
>>> import sys
>>> sys.platform #要加上sys. 命名空间来访问platform变量
'linux'
>>> from sys import platform
>>> platform #相对于在自己的命名空间中,复制新建了一个platform变量
'linux'
>>> from sys import * #将所有顶层的变量都复制到该模块中
>>> platform
'linux'
>>> maxsize
9223372036854775807
>>> path
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/home/liximin/.local/lib/python3.5/site-packages', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
>>>
import 只在第一次执行。执行后相关模块会载入内存,如果已经导入,在后续执行import语句时,就不有任何作用。导入模块是一个很消耗资源的操作,第二次导入不会重新执行模块代码,而是从模块表中取出已创建的模块对象。
import和from是赋值语句
- import语句相当于将模块对象赋值给变量名,所以在调用模块中的变量时,会用到类似对象的操作( module.name)来访问特定模块中的变量。
- from语句是将其他模块中的变量全部赋值给本模块中同名对象。所以可以直接用变量名访问。
>>> platform=12
>>> platform
12
>>> from sys import platform #from语句是直接赋值同名变量,有覆盖变量效果
>>> platform
'linux'
>>> sys.platform
'linux'
>>> sys.platform=12
>>> sys.platform
12
>>> import sys #import语句只在第一次导入时有作用
>>> sys.platform
12
>>>
from语句有覆盖命名空间中同名变量的陷阱。简单模块一般建议使用import语句,这样只用通过模块名来访问被导入的变量,模块与模块之间有很清晰的分隔。在明确了只是使用模块中某个变量时才使用from语句,有利于代码的简洁。
模块命名空间
模块最好理解为变量名的封装,就是让其它模块看到该变量名的场所。模块对应于Python文件,包含在模块中的变量,就是在文件顶层赋值的所有变量名。模块就是命名空间,而模块中的变量就是模块对象的属性。
- 模块语句会在首次导入时执行。系统中,模块在第一次导入时建立Python空对象,并依次执行文件中的语句。
- 顶层的赋值语句会创建模块属性。赋值语句包括 = 和 def语句。执行文件语句的过程中,就会在模块对象内穿件模块属性。
- 模块的命名空间可以通过内置方法dir()或者模块的属性__dict__获取。
- 模块是一个独立的作用域,在模块最外层的本地作用域就是全局作用域。
导入操作不会赋予被导入文件中的代码对上层代码的可见性,导入的模块只能发挥自己的功能。
- 函数绝对无法看见其它函数内部的变量名,除非它们从物理上处于这个函数内部
- 模块程序代码无法看到其它模块内的变量名,除非执行了导入。可以看到导入的模块中任意深的嵌套模块的变量
模块重载:reload
前面讲到模块只能在第一次导入时有效,重复导入不会改变内存中的现有值。
在Python程序继续执行的前提下,修改后的模块可以使用函数reload对模块进行动态重载。
- reload是Python中的内置函数,而不是语句
- 传给reload的对象是已经存在(已经导入)的模块对象,而不是变量名
- reload在Python3.0中需要执行(from imp import reload)导入后使用
- 一般使用方法是,在import模块后,重新编辑模块,不停止python程序的情况下,执行reload将其重载。
reload会在当前python运行的环境下,重新执行修改后的模块,并且用新的模块覆盖现有模块对象(命名空间)。
旧模块顶层的变量名可能更换新值。通过import语句导入的模块,都会受到影响,因为reload语句是将模块重载,内存中模块对象已经改变。因from语句是复制操作,在reload之前的from操作不会受到影响。