python——模块介绍
目录
一、什么是模块
模块就是一系列功能的集合体
二、模块四种通用的类别
1、 一个python文件就是一个模块,文件名为test.py,模块名为:test
2、盛放有多个py文件的文件夹也是一个功能的集合体,也就是一种模块,相当于一种超级模块,称之为:包
3、已被编译为共享库或DLL的C或C++扩展
4、使用C编写并链接到python解释器的内置模块
三、模块三种来源
1、自带的模块: 内置模块、标准库
print(type(print))
2、第三方模块
pip3 install requests
import time
print(type(time))
3、自定义的模块: 一个python文件就是一个模块,文件名为test.py,模块名为:test
四、为何要用模块
1、内置以及第三方模块: 拿来主义,提升效率
2、自定义模块:可以将程序的各个部分功能提取出来 放到一个模块中 供大家使用
好处是:减少代码冗余,程序组织结构更加清晰
五、如何用模块
1、首次导入模块会发生3件事
1、执行spam.py
2、产生spam.py的名称空间,将spam.py运行过程中产生的名字都丢到spam的名称空间中
3、在当前文件中产生一个名字spam,该名字指向2中产生的名称空间
print('from the spam.py')
money = 1000
def read1():
print('spam模块', money)
def read2():
print('spam模块')
def change():
global money # global修改全局变量
money=0
2、使用模块之import
import导入模块在使用时必须加前缀 “模块."如:spam.
优点:肯定不会与当前名称空间中的名字冲突
缺点:加前缀显得麻烦
#模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下
#test.py
import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
import spam
import spam
import spam
'''
执行结果:
from the spam.py
'''
3、被导入的模块有独立的名称空间
测试一:money与spam.money不冲突
#test.py
import spam
money=10
print(spam.money)
'''
执行结果:
from the spam.py
1000
'''
测试二:read1与spam.read1不冲突
#test.py
import spam
def read1():
print('========')
spam.read1()
'''
执行结果:
from the spam.py
spam模块 1000
'''
测试三:执行spam.change()操作的全局变量money仍然是spam中的
#test.py
import spam
money=1
spam.change()
print(money)
'''
执行结果:
from the spam.py
1
'''
4、可以以逗号为分隔符在一行导入多个模块
# 不建议在同一行导入多个模块
import spam,foo,time
# 建议分开导入,如下:
import spam
import foo
import time
5、from...import...导入模块
优点:无需加前缀,代码更为简洁
缺点:容易与当前名称空间中的名字冲突
From...import...发生的三件事情
1、执行spam.py文件
2、会触发模块文件的运行,产生一个模块的名称空间,将运行模块文件过程中产生的名字都丢到模块的名称空间
3、在当前名称空间中产生一个名字如:money,该名字指向模块的名称空间中的那个money
from...import...使用
from spam import money
from spam import read1
from spam import read2
from spam import change
案例:Run.py
from spam import money
from spam import read1
from spam import read2
from spam import change
money = 20000 # 与spam.py重名时,会以当前文件定义为准
print(money) # 输出:20000
print(read1)
print(read2)
print(change)
read1() # 输出:1000
def read1(): # 与spam.py重名时,会以当前文件定义为准
print(money) # 输出:20000
read1()
Spam.py
print('from the spam.py')
money = 1000
def read1():
print('spam模块', money)
def read2():
print('spam模块')
def change():
global money # global修改全局变量
money=0
from...import*(大多数不建议使用)
*导入模块中所有的名字
# 可以在spam.py文件中写入:
# __all__ = ["money","read1"]
# __all__控制被导入文件的*导入的具体个数
# run.py
from spam import *
起别名
from spam import money as m,read1 as f
print(m)
f()
六、模块循环导入问题案例
分析
问题主要出在,模块导入一遍后,加载名称空间,会运行模块的代码,最后在当前位置拿到名字,如果第二次导入,就直接不用运行前两部,直接拿到名字,所以循环导入第二次就会产生致命的问题。
先执行run.py,造名称空间并运行代码
---->执行import m1,开始导入m1并运行其内部代码--->打印内容"正在导入m1"
--->执行from m2 import y 开始导入m2并运行其内部代码--->打印内容“正在导入m2”
--->执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错
解决方式一:直接把名字提上来
解决方式二:导入语句放到函数中
利用函数定义阶段不会运行的特点
七、py文件区分两种用途:模块与脚本
编写好的一个python文件可以有两种用途:
一:脚本,一个文件就是整个程序,用来被执行
二:模块,文件中存放着一堆功能,用来被导入使用
区别:
1、作为脚本运行,直接右键运行该pytohn文件
2、作为模块,被import导入到其他文件中
python为我们内置了全局变量__name__:
当文件被当做脚本执行时:name 等于'main'
当文件被当做模块导入时:__name__等于模块名
作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
if name == 'main':
案例
run.py
import m1 #无需再跑到run.py执行
m1.py
def f1():
print('from f1')
def f2():
print('from f2')
if __name__ == '__main__': # 把当前文件当成导入文件,直接执行pytohn.m1.py
f1()
f2()
八、模块搜索路径优先级
无论是import还是from...import,在导入模块时,都涉及查找问题
模块的查找顺序
-
内存
-
内置模块
-
硬盘:按照sys.path中存放的文件顺序依次查找要导入的模块
import sys 值为一个列表,存放了一系列的对文件夹 其中一个文件夹是在当前执行文件所在在的文件夹 print(sys.path)
import m1 # 内存中已经有m1 import time time.sleep(10) import m1 m1.f1()
了解
# sys.modules查看已经加载到内存的模块
import sys
import foo # foo = 模块的内存地址
del foo
print(sys.modules)
# sys.path.append() 添加文件到环境变量
import sys
sys.path.append('/Users/yueying/PycharmProjects/16期新/day14/模块from')
import m1
m1.f1()