什么是模块?
模块就是一系列功能的集合。在python中,一个py文件就是一个模块,文件名为mytest.py,则模块名为mytest,导入模块就可以引用模块中已经写好的功能和变量。
为什么要使用模块?
使用模块的目的是为了提高开发效率,站在巨人的肩膀上进行开发,保证了代码的重用性,又增加了程序的可维护性。
模块的分类?
模块的表现形式?
使用模块的目的是为了提高开发的效率,那么我们该如何导入模块来供我们使用呢?下面介绍模块的导入方式。
通过import加模块名,则表示对模块的导入。
有如下代码文件:
# test1.py 导入文件
num = 100
def get_num():
print(x)
def change():
global num
num = 0
# start.py 执行文件
# 在学习模块的时候,首先分清楚谁是执行文件,谁是导入文件
import test1 # 导入的模块test1,注意不要加后缀
num = 200
x = test1.num # 引用模块test1中num的值赋值给当前名称空间中的变量x
print(x)
test1.get_num() # 调用模块test1中的get_num()函数
test1.change() # 调用模块test1中的change()函数
模块被导入时注意:
模块会执行,但是导入多次,只会执行一次。
模块首次导入时发生了哪些事?
注意:在start.py的名称空间中有与test1.py的名称空间中有相同的名字,但是在使用模块名称空间中的名字时,会通过test1.加名字来引用,所以不会出现名称冲突的问题。
from…import…与import语句基本一致,唯一不同的是:使用import test1导入模块后,引用模块中的名字都需要加上test1.作为前缀,而使用from test1 import num,get_num,change来导入,start则可以在当前执行文件中直接引用模块test1中的名字,如下代码所示:
from test1 import num
from test1 import get_num,change
print(num)
get_num()
change()
使用from…import…导入模块时注意:
文件作为模块被导入时,模块文件会执行。
from…import句式首次被导入时发生了什么?
连续导入:
from test1 import num,get_num,change
使用as来起别名
as既可以给模块起别名,也可以给模块中的某一个名字其别名
示例:
# my_first_model.py
num = 100
def get_num():
print(x)
def change():
global num
num = 0
# start.py
import my_first_model as model
print(model.num)
model.get_num()
model.change()
from test1 import num as a
print(a)
连续导入
可以一个句式导入多个模块,每个模块之间用逗号隔开。
示例:
# 方式一:
import time
import os
import sys
# 方式二:
import time,os,sys
通用导入
在使用from…import…句式时,可以使用*
号来表示导入模块中的所有名称。
from test1 import *
print(num)
get_num()
change()
注意:模块的编写者可以通过在自己的文件中定义__all__
变量来控制*
号代表的意思。
# first.py
num = 100
def get_num():
print(x)
def change():
global num
num = 0
__all__ = ['num','get_num']
# start.py
from first import *
print(num) # 可用
get_num() # 可用
change() # 不可用
因为一个python文件,可以是执行文件,也可以是被导入文件,那么我们该如何来区分呢?python中通过__name__
的内容来进行区分。
注意:
如果在执行文件中,__name__
的值是__main__
,并且是字符串类型。
如果作为模块时,__name__
的值被赋予模块名。
作为模块的开发者,可以在文件末尾基于__name__
在不同应用场景下的值的不同来控制文件执行不同的逻辑。
# test.py
if __name__ == '__main__':
test.py被当做脚本执行时运行的代码
else:
test.py被当做模块导入时运行的代码
循环导入指的是在一个模块导入的过程中导入另外一个模块,而在另外一个模块中又返回来导入第一个模块中的名字,由于第一个模块尚未加载完毕,所以引用失败、抛出异常,究其根源就是在python中,同一个模块只会在第一次导入时执行其内部代码,再次导入该模块时,即便是该模块尚未完全加载完毕也不会去重复执行内部代码。我们从以下例子来做出分析:
# m1.py
print('正在导入m1')
from m2 import y
x='m1'
# m2.py
print('正在导入m2')
from m1 import x
y='m2'
# start.py
import m1
先执行start.py
,执行import m1,开始导入m1,并运行其内部代码,打印内容"正在导入m1",然后执行from m2 import y 开始导入m2并运行其内部代码,打印内容“正在导入m2”,再执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错。
解决方案:在文件的最后导入模块
# m1.py
print('正在导入m1')
x='m1'
from m2 import y
# m2.py
print('正在导入m2')
y='m2'
from m1 import x
# start.py
import m1
结论:
循环导入问题是不允许出现的,如果出现,则是程序设计不合理。
如果在你的执行文件中找不到模块的时候,解决方案:把模块所在的路径加到sys.path中。
面向过程编程, 核心是”过程“二字,即先干什么,在干什么,最后干什么,表示一件事的执行步骤。面向过程编程不是一门技术,而是一种思想。
举例:把大象放冰箱分几步?
优点:使复杂的问题简单化
缺点:扩展性差
使用场景:在对扩展性要求不高的项目中可以使用面向过程的思想。