模块导入
代码格式的发展历程:
面条版 ---> 函数版 ---> 文件版 ----> 文件夹版 -----> 微服务(多个小项目)
模块
1. 模块是什么
模块(module):一般情况下,是一个以.py为后缀的文件。其他可作为module的文件类型还有”.pyo”、”.pyc”、”.pyd”、”.so”、”.dll”,但Python初学者几乎用不到
2. 模块的作用:
- 模块可以放多个函数,然后把多个函数分成多个文件,隐藏隐藏代码细节
- 简化操作,不需要重复开发相同的功能,直接使用即可
模块的4种形式:
1. 自定义模板
2. 第三方库,需要自己下载,如:requests
3. 内置模块 直接使用。如time
4. 文件夹版,在python中就叫做包
导入模块的两种形式
1. import time
import time
# import 模块导入时发生的三件事
# 1. 打开time文件
# 2. 把time文件内容读入python解释器的内存,然后把time文件内容放入特定的模块,然后放入全局名称空间
# 3. 使用功能时,直接去模块的名称空间内部寻找time的方法
'''
总结:
1. 优点:time里面有的方法,全都有
2. 缺点:占用内存
'''
2. from...import...
from timeinport slepp
# 1. 打开time文件
# 2.
'''
总结:
优点:
1. 直接使用sleep(0)就行了
缺点:
1. 如果当前项目中也存在sleep()方法,会发生冲突。
'''
3. from...import...其他的形式
from time import * # 把time模块中的所有函数引入,相当于import time
from time import sleep,time # 从time模块中引用sleep,time模块
from time inport *
__all__ = [f1,lis] # 限定当前导入哪些模块
import time as t # 导入time模块,并改名为t
t.sleep(1)
循环导入问题
# m.py文件
from n import x
y = 10
# n.py文件
from m import y
x = 20
以上就会导致循环导入:
解决方法
1. 在导入变量之前,让变量提前生成。
# m文件
y = 10
print("from m")
from n import x
print("x的值为%d"%x)
# 运行m文件的结果为:
'''
from m
from n
from m
x的值为20
y的值为10
x的值为20
'''
# 总结:
步骤一:m文件运行到第3行时,打印“from m”
步骤二:m文件运行到第4行时,m文件中导入模块n,即执行模块n中的代码。n文件中的第2行代码即找到了x变量,但仍然继续执行n文件,然后n文件的第3行打印“from n”
步骤三:当n文件执行到第4行时,导入模块m,即执行模块m中的代码,m文件中的第2行代码即找到了y变量,但是也仍然继续执行m文件,然后执行m文件的第3行,打印“from m”
步骤四:当m文件运行到第4行时,x变量已经导入了,此时就跳过第4行代码,然后执行m文件的第6行代码,即打印“x的值为20”
步骤五:返回到步骤3,此时才算是把n文件中的m模块执行完,此时运行n文件第6行代码,即打印“y的值为10”
步骤六:返回到步骤2,此时才算是把n模块中的代码执行完,于是继续运行m文件的第6行,即打印“x的值为20”。
# n文件
x = 20
print("from n")
from m import y
print("y的值为%d"%y)
此时方案存在另外一个问题。即我运行m文件,只想打印两行内容(from m和x的值),但是现在却打印了6行。那如何才能避免这样的情况。不用着急,python给我们提供了一个方法_name_
# m文件
y = 10
from n import x
if __name__ == "__main__"
print("from m")
print("x的值为%d"%x)
# 运行m文件的结果为:
'''
from m
x的值为20
'''
# n文件
x = 20
from m import y
if __name__ == "__main__"
print("from n")
print("y的值为%d"%y)
上述的现象的原理为:当程序在本文件中执行时,本文件中__name__变量的值为
_main_,如果程序不是在本文件中执行,而是通过模块引入,那么name的名称则不为main。
有句经典的概括了这段代码的意义:“Make a script both importable and executable”
意思就是说让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可执行。
2. 将需要导入的模块封装到函数里面
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'
模块的搜索路径:
1. 去内存中找
# test.py
import m1 # 从m1.py文件中导入的,然后会生成m1模块的名称空间
import time
# 删除m1.py文件,m1模块的名称空间仍然存在
time.sleep(10)
import m1 # 不报错,一定不是从文件中获取了m1模块,而是从内存中获取的
2. 去内置模块中找
# time.py
print('from time')
# test.py
import time # 无任何打印
执行test.py文件,无任何打印,所以他先去内置模块中找了
3. 环境变量中找
import sys
print(sys.path)
# b/a/m1.py
# b/test.py
import m1 # 报错
sys.path.append('b/a')
import m1