模块导入
目录
模块
什么是模块?
模块是一系列功能的集合体,而函数是某一个功能的集合体,因此模块可以看成是一堆函数的集合体,一个py文件内部可以放一堆函数,因此一个py文件就可以看成一个模块,py文件名,就是模块名。
模块的四种形式:
1.内置模块:使用c编写并链接到python解释器的内置模块
2.第三方模块:已被编译为共享库或DLL的C或 C++扩展
3.包:把一系列模块组织到一起的文件夹(文件夹下有一个__init_.py
文件,该文件称之为包)
4.自定义模块:自己写的.py
文件,在文件内写入一堆函数,则被称为自定义模块,即使用python编写的.py
文件
为什么用模块?
1.用第三方或者内置模块拿来就用,极大的提升开发的效率
2.自定义模块,将自己的程序用到公共功能,写一个python文件,然后程序的各部分可以导入模块
如何用?
使用import / from .. import
import 与from...import:
导入模块的过程:
import + 模块名
1.为模块开辟一个名称空间,命名为模块名
2.把模块所有的代码读入空间,执行模块对应的文件
3.通过 模块名.
+ 模块中的方法
注意:模块的重复导入会直接饮用之前创造好的结果,不会重复执行模块的文件,模块只会在内存开辟一次空间
from 模块名 import 方法名
1.为模块开辟一个名称空间,命名为模块名
2.把模块所有的代码读入空间,执行模块对应的文件
3.通过 读入模块中的方法
,可以直接使用方法名
-
优点:不用加前缀,代码更加精简
-
缺点:容易与当前执行文件中名称空间中的名字冲突
#使用多个方法,如 : time模块
from time import sleep, time
#导入所有功能
from time import *
#导入多个模块
import sys,time #不推荐
#在 from 模块 import 模块方法
__all__ = [] #只允许导入列表内的变量
相同点:
1.两者都会执行模块对应的文件,两者都会产生模块的名称空间
2.两者调用功能时,需要跑到定义时寻找作用域关系,与调用位置无关
不同点:
调用功能时,import需要加前缀;from...import...不需要加前缀
循环导入问题:
#m1.py
print('from m1.py')
from m2 import x
y = 'm1'
--ImportError: cannot import name 'y'
1. 创建m2的名称空间
2. 执行m2.py,将执行产生的名字丢到m2.py
3. 在当前执行文件中拿到m2.x
#m2.py
print(from m2.py)
from m1 import y
x = 'm2'
--ImportError: cannot import name 'x'
1. 创建m1的名称空间
2. 执行m1.py,将执行产生的名字丢到m1.py
3. 在当前执行文件中拿到m1.y
#run.py
import m1
--ImportError: cannot import name 'y'
创建m1的名称空间
执行m1.py,将执行产生的名字丢到m1.py
在当前执行文件中拿到m1
解决方法:
使用函数定义阶段只识别语法的特性解决循环导入的问题,我们也可以从本质上解决循环导入的问题,但是最好的解决方法是不要出现循环导入。
#--方案一
#m1.py
print('from m1.py')
def func1():
from m2 import x
print(x)
y = 'm1'
# m2.py
print('from m2.py')
def func1():
from m1 import y
print(y)
x = 'm2'
#方案二
# m1.py
print('from m1.py')
y = 'm1'
from m2 import x
# m2.py
print('from m2.py')
x = 'm2'
from m1 import y
模块的搜索路径:
--模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径
模块的搜索路径指的就是在导入模块时需要检索的文件夹
导入模块时查找模块的顺序是:
-
先从内存中已经导入的模块中寻找
-
内置的模块
-
环境变量sys.path中找
python文件的两种用途:
1.执行文件
2.模块文件
编写好的一个python文件可以有两种用途:
1.脚本,一个文件就是整个程序,用来被执行
2.模块,文件中存放着一堆功能,用来被导入使用
x = 1
def f1():
print('from f1')
def f2():
print('from f2')
if __name__ == '__main__': #判断
f1()
f2()
# __name__ == '__main__'不成立, __name__ != '__main__'
# 当testt为模块文件时,__name__等于文件名
# __name__是每个文件独有的,当该文件作为执行文件运行时,__name__等于'__main__';当该文件作为模块文件导入时,__name__等于文件名