模块导入
import导入模块具体原理:
先从sys.modules里查看该模块名是否存在,已经被导入
如果没有被导入,则当前执行文件目录为准,依据sys.path里的路径寻找模块名
找不到模块名则报错,找到模块后,就为这个模块创建命名空间
把该模块的变量,函数名都存放在该命名空间里
import...as...
作用:导入模块并给模块重命名
它的一种用法:
db_type=input('>>: ') if db_type == 'mysql': import mysql as db elif db_type == 'oracle': import oracle as db db.update()
模块导入注意事项:
模块最好分多行导入
先导入内置模块,再导入扩展模块,最后是自己写的模块
from...import...:单独从一个模块里导入一个函数或者变量
from...import... 与 import的区别:
from...import...会把函数或者变量名导入到当前命名空间里,可能会覆盖当前命名空间里已存在的命名,而import会给模块创建单独的命名空间,不会冲突
from...import...只会导入一两个变量名,而import会把模块里所有变量,函数加载到命名空间里,浪费内存
from...import...里函数还是会引用原来模块里的变量,因为变量实际上就是一个内存地址
from...import*:把模块里所有变量,函数导入到当前模块命名空间,一般不推荐用
在导入模块文件时,__all__与from...import* 与搭配使用才会生效,__all__ = ['read', money],它限制from...import*可以导入的变量名和函数名(不适用__all__变量时,from...import*会导入所有变量和函数名)
需求:当一个文件的功能需要单独调试时,不希望带着其他文件的代码一起运行,而又不希望修改这个文件的代码。
__name__ 用法:
当文件被当做一个脚本去执行, __name__ = '__main__
当文件被当做一个模块被导入时, __name__=‘当前模块的名字’
if __name__ == '__main__':(加了这一句后,就不用在单独调试模块时,需要写调用函数的代码,作为模块,就得删掉这些调用语句了) 执行代码
包导入
解释:单独一个模块文件已经不能满足功能需求了,需要增加更多的代码,但是也不能一直写在一个文件里。所以,把一些模块文件集中起来放在一个文件夹里,称为一个包。
from...import...使用原则:
(所有)凡是在导入时带点的,点的左边都必须是一个包。在导入后就没有这个限制了,包,模块,函数,类都可以直接用点的方式调用自己属性
from...import...:import后带的不可以带点,必须是一个单独的包、模块。错误用法:from a import b.c
使用import 导入包(from...import...没有这个问题,不需要处理__init__文件),会执行__init__文件下的代码。通常,包的__init__文件都未作处理,需要在每个__init__下写入导入语句,使得下面代码可以执行正确
#在glance.__init__.py中 from .api.policy import get from .api.versions import create_resource from .cmd.manage import main from .db.models import register_models __all__=['get','create_resource','main','register_models']
import glance glance.cmd.manage.main()
在使用import和from...import...前,一定要弄明白当前文件是被当做脚本执行的还是被当做模块被其他文件导入的。原因:执行脚本所在的目录决定了sys.path差异,因此,使用import时,会出现找不到模块的现象。
相对导入和绝对导入
绝对导入:
相对导入:只出现在包里,如果包里有相对导入了,就不能用绝对导入了。
原因:导入一个包时,sys.path确定,当前执行目录已经知晓,导入内存中时,根据相对导入建立一个包的关系树。当用包里的模块当做脚本执行了,sys.path发生改变,相对导入(./..)失去作用,不在内存里,找不到目录关系。(表现为:只能向里层方向找,不能向外层方向找,绝对导入也是不可以从里层往外层方向找的)
所以,相对导入是在执行脚本所在目录(sys.path)确定后为前提情况,因此,用相对导入写的包,里面的模块文件就不能单独执行了。from . import a 这种语法在脚本文件里是错误的。
相对路径和绝对路径的优缺点
绝对路径 :
不管在包内部还是外部 导入了就能用
不能挪动,但是直观
相对路径:
可以随意移动包 只要能找到包的位置,就可以使用包里的模块
包里的模块如果想使用其它模块的内容只能使用相对路径,使用了相对路径就不能在包内直接执行了
通常情况,只需要在包外部调用包的模块,不需要去单独执行包里面模块文件的话(通常是已经成型的包),不管包里面的模块是如何相互调用的,使用相对路径