模块
---恢复内容开始---
什么是模块
模块就是python代码的文件
为什么要有模块
某些代码需要在不同的文件中重复使用,代码可读性差,写代码困难大
导入模块时做的事
执行python解释器时,就已经在内存中加载了一些内置模块了
import sys print(sys.modules) {'builtins': <module 'builtins' (built-in)>, 'sys': <module 'sys' (built-in)>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_thread': <module '_thread' (built-in)>, '_weakref': <module '_weakref' (built-in)>, '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'nt': <module 'nt' (built-in)>, 'winreg': <module 'winreg' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, 'encodings': <module 'encodings' from 'C:\\Python36\\lib\\encodings\\__init__.py'>, 'codecs': <module 'codecs' from 'C:\\Python36\\lib\\codecs.py'>, '_codecs': <module '_codecs' (built-in)>, 'encodings.aliases': <module 'encodings.aliases' from 'C:\\Python36\\lib\\encodings\\aliases.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from 'C:\\Python36\\lib\\encodings\\utf_8.py'>, '_signal': <module '_signal' (built-in)>, '__main__': <module '__main__' (built-in)>, 'encodings.latin_1': <module 'encodings.latin_1' from 'C:\\Python36\\lib\\encodings\\latin_1.py'>, 'io': <module 'io' from 'C:\\Python36\\lib\\io.py'>, 'abc': <module 'abc' from 'C:\\Python36\\lib\\abc.py'>, '_weakrefset': <module '_weakrefset' from 'C:\\Python36\\lib\\_weakrefset.py'>, 'site': <module 'site' from 'C:\\Python36\\lib\\site.py'>, 'os': <module 'os' from 'C:\\Python36\\lib\\os.py'>, 'errno': <module 'errno' (built-in)>, 'stat': <module 'stat' from 'C:\\Python36\\lib\\stat.py'>, '_stat': <module '_stat' (built-in)>, 'ntpath': <module 'ntpath' from 'C:\\Python36\\lib\\ntpath.py'>, 'genericpath': <module 'genericpath' from 'C:\\Python36\\lib\\genericpath.py'>, 'os.path': <module 'ntpath' from 'C:\\Python36\\lib\\ntpath.py'>, '_collections_abc': <module '_collections_abc' from 'C:\\Python36\\lib\\_collections_abc.py'>, '_sitebuiltins': <module '_sitebuiltins' from 'C:\\Python36\\lib\\_sitebuiltins.py'>, 'sysconfig': <module 'sysconfig' from 'C:\\Python36\\lib\\sysconfig.py'>, 'atexit': <module 'atexit' (built-in)>}
在第一次导入某个模块时,会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有直接引用。
如果没找到就从sys.path给出的目录列表中依次寻找文件。
所以模块的查找顺序是:内存中加载的>sys.path路径中包含的模块
所以给模起名时不要起内置模块的名字,比如re模块,re模块虽然是内置模块,但却没有被加载到内存中,当你在运行文件的目录中创建一个名为re的python文件时,在调用就会调用到你创建的名为re的python文件
导入模块时,如果模块不存在sys.modules,才从sys.path给的路径中去查找
sys.path决定某个模块能不能被找到
import sys print(sys.path) #['', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36', 'C:\\Python36\\lib\\site-packages']
第一个位置就是运行python的位置
当导入模块时,按照这个顺序从前往后依次查找
在初始化后,python程序可以修改sys.path,路径放到前面的优先于标准库被加载
import sys sys.path.append('/a/b/c/d') sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索
导入模块时,会创建名为模块名的一个命名空间,在这个命名空间中执行代码
模块的导入
模块导入的几种方法
import 模块名
import os #模块名.函数名()就可执行模块中的函数 #模块名.函数名就可调用模块中的变量 #使用import方式导入的模块中的内容和自己文件中的内容不会冲突。 #因为模块中的变量和函数存在这个模块开辟的局部命名空间中
import 模块名,模块名,模块名
import os,sys,re #一次导入多个模块,但是一般不这么用
导入时,先导入内置模块
再倒入拓展模块
最后导入自定义模块,各种模块用空行隔开
import os
import sys
import re
#上面是内置模块
import django
#上面是拓展模块
#最后是自定义模块
import 模块名 as 新名字
给模块重命名,重命名之后之前的名字就失效了,新名字可以直接使用
#当模块名十分复杂时,可以重命名 #import 十分复杂的函数名 as a #在使用时就用a.变量名。十分复杂的函数名就没用了 #当导入的模块和文件中的变量重名的时候 #当兼容多个模块的操作相同的时候 举个栗子 mysql数据库和oracle数据库的操作相同 只需要在前面判断,然后改成相同的名字,就可以不用改动下面的内容 # if 是mysql数据库: # import mysql as db # elif 是oracle数据库: # import oracle as db # db.open # db.write
form 模块名 import 变量名
# from import的用法 会直接将导入的内容放在全局 # 如果有同名,就会发生覆盖 # 但是模块中用到的变量和模块中方法是一种绑定关系 #即使你覆盖了导入的变量,但是你在调用导入的方法时,方法调用这个变量,依然是去调用模块中的这个变量
使用form import 来导入多个值和改名
from 模块名 import 变量名 as 新名字,变量名 as 新名字 #导入内容用逗号隔开
使用form import导入模块中的全部内容
from 模块名 import * __all__=["",""] #当使用这种模式时,在模块中可以设置__all__变量来限制 #默认是没有这个变量,可以导入模块中的全部名字 #设定后只能导入__all__中的名字
把模块当作脚本执行
我们可以通过模块的全局变量__name__来查看模块名:
当做脚本运行:
__name__ 等于'__main__'
当做模块导入:
__name__= 模块名
作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
if __name__ == '__main__':
print(__name__) #当在模块内打印__name__时,结果是__main__ #当这个拥有这个代码的模块被导入时,打印的就是模块名。 #可以在模块中设置 if __name__=="__main__": #下面是在模块中执行的内容 #如果导入这个模块,则其中的内容就不会执行
编译python--导入模块后,会生成一个pyc文件,就是python的编译文件
为了提高加载模块的速度,强调强调强调:提高的是加载速度而绝非运行速度。python解释器会在__pycache__目录中下缓存每个模块编译后的版本,格式为:module.version.pyc。通常会包含python的版本号。例如,在CPython3.3版本下,my_module.py模块会被缓存成__pycache__/my_module.cpython-33.pyc。这种命名规范保证了编译后的结果多版本共存。
Python检查源文件的修改时间与编译的版本进行对比,如果过期就需要重新编译。这是完全自动的过程。并且编译的模块是平台独立的,所以相同的库可以在不同的架构的系统之间共享,即pyc使一种跨平台的字节码,类似于JAVA火.NET,是由python虚拟机来执行的,但是pyc的内容跟python的版本相关,不同的版本编译后的pyc文件不同,2.5编译的pyc文件不能到3.5上执行,并且pyc文件是可以反编译的,因而它的出现仅仅是用来提升模块的加载速度的。
python解释器在以下两种情况下不检测缓存
1 如果是在命令行中被直接导入模块,则按照这种方式,每次导入都会重新编译,并且不会存储编译后的结果(python3.3以前的版本应该是这样)
python -m my_module.py
2 如果源文件不存在,那么缓存的结果也不会被使用,如果想在没有源文件的情况下来使用编译后的结果,则编译后的结果必须在源目录下
提示:
1.模块名区分大小写,foo.py与FOO.py代表的是两个模块
2.你可以使用-O或者-OO转换python命令来减少编译模块的大小

-O转换会帮你去掉assert语句 -OO转换会帮你去掉assert语句和__doc__文档字符串 由于一些程序可能依赖于assert语句或文档字符串,你应该在在确认需要的情况下使用这些选项。
3.在速度上从.pyc文件中读指令来执行不会比从.py文件中读指令执行更快,只有在模块被加载时,.pyc文件才是更快的
4.只有使用import语句是才将文件自动编译为.pyc文件,在命令行或标准输入中指定运行脚本则不会生成这类文件,因而我们可以使用compieall模块为一个目录中的所有模块创建.pyc文件

浙公网安备 33010602011771号