模块
模块理论
- 定义
模块就是供直接调用的已经写好的功能结合体 - 开发模块的目的
提升开发效率 - 模块来源
- 内置模块
解释器自带的模块,可以直接调用,不需要下载 - 自定义模块
自己编写的代码进行封装的模块 - 第三方模块
别人编写的发到网上,下载之后可以使用的模块
- 内置模块
- 模块的形式
- python文件
- 多个Python文件组成的文件夹
- 已被编译为共享库或DLL的c或C++扩展(了解)
- 使用C编写并链接到python解释器的内置模块(了解)
模块的导入方式
方式一:import+被导入模块名
import time
print(time.time()) # 1648362858.5759282
'''
导入模块内部所发生的事:
1. 执行执行文件,产生一个执行文件的名称空间
2. 执行导入命令,执行被导入模块文件,产生被导入模块的名称空间
3. 在执行文件名称空间里,产生一个模块名指向被导入模块的名称空间
4. 通过该模块名,可以访问被导入模块的名称空间里的所有数据
特点:
可以直接通过模块名点的方式,访问模块里的变量名,并且不会与执行文件里的变量名冲突
'''
方式二:from A import B 从A指名道姓的导入B
from A import b
print(b) # b = 'kevin'储存在文件A里 结果为kevin
'''
导入模块内部所发生的事:
1. 执行执行文件,产生一个执行文件的名称空间
2. 执行导入命令,执行被导入模块文件,产生被导入模块的名称空间,存放所有被导入模块执行过程中韩国的所有数据名
3. 然后把import后面的文件名拿到当前文件内使用
特点:
不需要通过点的方式,直接使用被导入模块里的数据。不过这里需要注意与执行文件里的名字可能发生冲突,并且只能使用import后面的名字,其他的不能用。
'''
需要注意,模块只能导入一次,也就是说导入模块的命令只有第一次有效
补充知识
给模块命名(改名)
在模块名很复杂的时候,可以使用以下方法将模块名简化使用
import A as a # 将复杂的模块名A改为a
连续导入
import A, B ,C
from A import b, c, d
# 注意:连续导入多个模块 这多个模块最好有相似的功能部分 如果没有建议分开导入,如果是同一个模块下的多个变量名无所谓!!!
通用导入
from A import *
从A 导入A中的所有名字
# *表示md里面所有的名字 from...import的句式也可以导入所有的名字,如果模块文件中使用了__all__限制可以使用的名字 那么*号就会失效
循环导入问题
循环导入是指两个文件互相导入彼此,此种情况发生时可能导致名字未定义就使用的错误。应该精良避免循环导入的发生,被迫使用循环导入时,要保证用到的名字都被提前定义好。
避免循环导入的名字定义方式有两种:
- 将名字定义在导入命令上面
- 将名字定义在函数体代码内
这两种名字的第一方式,会导致名字的重复调用(部分代码的重复执行)
b = 'from b'
import A
print(A.a)
'''
执行结果为:
from a # 导入模块A时执行文件A打印的数据
from b # A里导入模块B时执行文件B打印的数据
from a # 执行文件执行时所打印的数据
'''
文件类型的判断
模块阶段的文件类型可以分为执行文件和被导入文件,可以用__name__判断文件类型
'''
__name__在执行文件里是__main__,在被导入文件里是被导入的文件名
'''
b = 'from b'
import A
if __name__ == '__main__': # 在执行文件里__name__是__main__
print(__name__) #__main__
print(A.a) # from a
模块的查找顺序
按以下顺序依次查找:
- 内存空间
- 内置模块
- sys.path
- 上述都找不到会报错
import A, time # 内存空间
time.sleep(20) # 睡眠时间删除文件A
print(A.a) # 模块A 加载到内存空间之后,即便删除文件A ,依旧能够获得文件A里的a数据
import time # 内置模块
print(time)
print(time.time())
import sys # sys.path
print(sys.path) # E:\\pythonProject2\\day018' 执行文件所在路径
更改文件查找路径的方式
# 方式一:添加路径进sys.path
import sys
sys.path.append('E:\pythonProject2\day018\B')
print(sys.path)
''' ['E:\\pythonProject2\\day018', 'E:\\pythonProject2\\day018', 'F:\\PyCharm\\plugins\\python\\helpers\\pycharm_display', 'D:\\Python36\\python36.zip', 'D:\\Python36\\DLLs', 'D:\\Python36\\lib', 'D:\\Python36', 'D:\\Python36\\lib\\site-packages', 'F:\\PyCharm\\plugins\\python\\helpers\\pycharm_matplotlib_backend', 'E:\\pythonProject2\\day018\\B']
'''
import A # 虽然在pycharm会飘红,但是依然可以执行
print(A.a) # from a
# 方式二:利用from……import……句式指定导入对象
from kat.cat.dog import dog # 通过点的方式进入下一级
print(dog.name) # from a
绝对导入与相对导入
'''
导入模块时,无论导入模块的句式是在执行文件或者是被导入文件里,都是执行文件的路径为准
1. 绝对导入
永远按照执行文件的路径为准一层层往下查找
2. 相对导入
相当于导入模块时打破了必须以执行文件所在路径为准的要求,只需要考虑当前模块所在的路径,然后用点号去查找其他文件
. 表示当前路径
.. 表示上一层
../.. 表示上上一层
相对导入只能在被导入文件中,不能再执行文件里
3. 推荐使用绝对导入
'''
包
'''
专业角度:
包是指内部含有__init__.py的文件夹
现实角度:
包是多个模块的结合体(文件夹内部存放多个模块,类似文件夹)
在导入包的时候 索要名字其实是跟包里面的__init__.py要
1.如果想直接通过包的名字使用包里面所有的模块 那么需要在__init__.py中提前导入
上述方式的好处在于__init__可以提前帮你准备好可以使用的名字
2.也可以直接忽略__init__的存在使用绝对导入即可
上述方式的好处在于不需要考虑包的存在 直接当成普通文件夹即可
'''