18、模块

一、模块介绍

模块就是一系列功能的集合体,我们的程序可以导入模块来复用模块里的功能。

我们使用模块的目的就是:1.拿来主义,极大地提升开发效率,2.解决代码冗余问题

1、模块分为四种类别

1、使用python编写的.py文件
2、把一系列模块组织到一起的文件夹(文件夹下有一个__init__.py文件,该文件夹称之为包)
3、使用c编写并链接到Python解释器的内置模块
4、已被编译为共享库或DLL的C或C++扩展

2、模块有三种来源

1、Python解释器自带的

(1)内置的

# 内置在Python解释器的模块
import time
print(time)  # <module 'time' (built-in)>

(2)标准库

# Python官方认为比较优秀的模块,收录在Python解释器里的
import os
print(os)  # <module 'os' from 'D:\\py3.6\\lib\\os.py'>

2、第三方库

由第三方提供的模块

3、自定义的库

自行定义的模块

二、模块使用

1、import

import spam
'''
首次导入模块会发生的三件事情
1.会触发spam.py运行,所以会产生一个模块的名称空间
2.运行spam.py的代码,将运行过程中产生的名字都丢到模块的名称空间中
3.在当前执行文件的名称空间中拿到一个名字spam,该名字就是指向模块的的名称空间
'''
import spam  # 后续的导入直接引用首次导入的成果,不会再重复显示

# 调用:必须用模块名和.作为前缀
spam.get()  # 调用模块spam的get函数

# 优点:因为每次加上前缀spam. 相当于指名道姓要引用spam名称空间的名字,不会和当前执行文件所在的名称空间中的名字起冲突

2、from...import...

from spam import money
# from + import和import首次导入发生的事情都差不多,唯一不同的是第三点,它会在当前执行文件的名称空间拿到后者money的名字,该名字是指向模块的名称空间对应的名字
# 后续导入直接引用之前的成果


get()  # 调用模块spam的get函数
# 优点:调用时无需加前缀,代码更简洁
# 缺点:容易和当前名称空间中的名字冲突,如果当前名称空间存在相同名字,则后定义名字会覆盖之前定义的名字

3、导入语法补充

3.1、起别名

import spam as f # 为导入的模块spam在当前位置起别名f,以后再使用时就用这个别名f
f.x
f.get()

3.2、*的使用

from spam import * # 把spam中所有的名字都导入到当前执行文件的名称空间中,在当前位置直接可以使用这些名字

a=x
get()
change()
obj=spam()
# 缺点:如果我们需要引用模块中的名字过多的话,可以采用上述的导入形式来达到节省代码量的效果,但是需要强调的一点是:只能在模块最顶层使用的方式导入,在函数内则非法,并且的方式会带来一种副作用,即我们无法搞清楚究竟从源文件中导入了哪些名字到当前位置,这极有可能与当前位置的名字产生冲突。

'''
模块的编写者可以在自己的文件中定义__all__变量用来控制*代表的意思
意味着使用在使用*的时候,只会导入列表内的代码
'''
__all__=['x','get'] 

三、模块搜索路径

1、导入模块的规范

先导入内置的模块,再导入第三方的,最后导入自定义的

2、查找模块的优先级

1.内存中已经加载过的

2.内置模块

3.sys.path路径中包含的模块

四、py文件两种用途

一个Python文件有两种用途,一种被当主程序/脚本执行,另一种被当模块导入,为了区别同一个文件的不同用途,每个py文件都内置了__name__变量,该变量在py文件被当做脚本执行时赋值为“__main__”,在py文件被当做模块导入时赋值为模块名

假如你是模块foo.py的开发者,可以在文件末尾基于__name__在不同应用场景下值的不同来控制文件执行不同的逻辑

if __name__ == '__main__':
    foo.py被当做脚本执行时运行的代码
else:
    foo.py被当做模块导入时运行的代码
posted @ 2021-04-03 16:57  黑影Poco  阅读(71)  评论(0)    收藏  举报