python模块
模块(module):一个.py文件就是一个模块。Python中有自带的模块,也有第三方的模块,第三方的模块需要自己去进行安装,而自带的模块则可以直接导入使用。
1. 如何导入模块?
导入模块其实就是在执行 .py 文件;开辟一块新内容,将内容加载到内存中。其流程如下:
1)想要使用模块,必须先要将模块加载进来,可以通过关键字 import 或 from 进行加载。import 模块的方式有以下几种:
2)根据搜索路径找到这个需导入的模块。可以查看 sys.path 变量来查看搜索路径,sys.path 是 python 的搜索模块的路径集,是一个list,有关路径
设置的变量的值都会最终设置到 sys.path 变量中,解释器会按照列表定义的路径顺序来查找模块,在第一个路径下搜索到了,就停止搜索。
下面来看下 sys.path 的路径组成有哪些?
a. 模块(.py文件)当前目录,即 sys.path 第一个路径是该模块的当前路径。
b. 如果不在当前目录,Python 则搜索在变量 PYTHONPATH 下的每个目录。PYTHONPATH 环境变量中输入相关的路径,不同的路径之间用逗号分开,如
果 PYTHONPATH 变量不存在,可以创建它!路径会自动加入到 sys.path 中。
c. 如果都找不到,Python会察看默认路径,由解释器配置。UNIX下,默认路径一般为/usr/local/lib/python/。
d. 我们也可以在 python 环境下直接修改 sys.path 的值,使用 sys.path.append(path) 添加相关的路径,但这个路径只是临时的,退出 python 环
境后自己添加的路径就会自动消失!
3)判断这个模块是否被导入过:
a. 如果没有被导入过:将被导入模块进行预编译,形成相对应的pyc文件。创建一个属于这个模块的命名空间。如果用户没有定义变量来引用这个模块的内
存地址的话,那么就使用模块的名称来引用这个模块的内存地址。如果用户使用 as 来指定变量接受这个内存地址的话,那么就将内存地址赋值给这个变
量,且下文在调用时只能使用这个变量进行调用不能再使用模块名进行调用了。然后执行这个模块中的代码。
b. 如果该模块已经被导入过:那么解释器不会重新执行模块内的语句,后续的 import 语句仅仅是对已经加载到内存中的模块的对象增加一次引用。
2. 模块的编译
python是一种解释性的语言,但其实它和java一样,是一门先编译后解释性的语言。
我们在运行 .py 文件后,会得到一个 xxx.pyc 的文件,该文件就是编译后生成的文件,称为预编译模块。事实上,我们执行 .py 文件时,解释器会先
寻找 .pyc 文件,如果找到,会首先检查 .py 文件的最后编辑日期和 .pyc 的编译时间,从而决定是否需要重新编译。若时间戳一致则直接载入内存,否
则就将程序编译为 pycodeobject 后存放在内存中,执行结束时,会将 pycodeobject 保存为 __pycache__ 文件夹下的 xxx.pyc 文件。
3. 模块的内建变量
Python中的模块(.py文件)在创建之初会自动加载一些内建变量,下面一一列举。
1) __doc__:文件注释,在py中代码最上方""" """里面一般写注释,系统会把文件注释自动存放在'_doc_'这个全局变量里。
""" 我是注释 """ print(__doc__) #我是注释
2) __file__:值为当前文件的存放路径和文件名,即值为全路径。
import os print(os.path.dirname(__file__)) # 提取出路径名 print(os.path.basename(__file__)) # 提取出文件名
3) __name__:标识模块的名字。
一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其它的 python 脚本中被调用(模块重用)执行。
1)当python文件 a.py 作为脚本直接执行的时候,__name__ 的值就会被系统设为 '__main__',可以在代码中进行判断,用以执行一个模块的某些功能。
2)当python文件 a.py 被import到其它python脚本 b.py,并执行 b.py 时,a.py中的 __name__ 会被置为文件名 a。
直接来看一个例子吧:
a.py的代码如下,直接执行a.py,可以看到输出的__name__值为__main__,条件判断成立,输出'exe by self'。
print(__name__) if __name__ == '__main__': print("exe by self") """ output: __main__ exe by self """
b.py的代码如下,执行b.py,此时没有再输出'exe by self'了,可知__name__值变了。
import a """ output: a """
4) __all__:__all__
是一个字符串list,用来定义模块中对于 from XXX import *
时要对外导出的符号,即要暴露的接口,但它只对 import *
起作用,
对 from XXX import XXX
不起作用。如果没有定义__all__,则变量会被全部导入。
举个例子,a.py代码如下:
__all__ = ['x', 'y', 'test'] x = 2 y = 3 z = 4 def test(): print('test')
再定义另一个b.py,代码如下:
from a import * print('x: ', x) print('y: ', y) print('z: ', z) # 出错:NameError: name 'z' is not defined test()
可以再手动导入,则不会报错:
from a import * from a import z print('x: ', x) print('y: ', y) print('z: ', z) # 运行正常 test()
5)__package__:包含该模块所在包的名字,若不存在包,则值为 None。