基本概念:
tips:
- 导入了包里面的文件后就会执行包的_init_.py文件
- 当导入的是一个包,不是一个文件时:
假如在test.py中要导入test1包中的tool模块,如果直接写:
import test1
print(test1.tool) # 报错,需要写成import test1.tool才能执行这一句
from test1 import tool
print(tool) # 或者加上from test1 import tool才能执行
如果在test1包中的_init_.py中加上:import test1.tool(不能写成import tool)。就在test.py中可以直接执行第一块代码而不会报错,因为导入了包里面的文件后就会执行包的_init_.py文件,执行import test1时就执行了_init_.py。
- 假如子包test1中还有一个子包test2,且test2里面有tools.py模块:
from test1.test2 import tool2 # 正确
from test1 import test2.tool2 # 错误,要确保import后面的是最简的
(可以理解为从test1中只可以看到test2,不能看到test2中的tool2)
- 导入了什么,就只能读取什么:
from test1 import tool
print(test1.tool) #报错,即使from了test1,也只能读取import了的tool
- from 模块 import *:
在test2.py中:
__all__ = ['num1', 'num2']
num1 = 1
num2 = 2
num3 = 3
_num4 = 5 # 加了下划线,表示私有变量,无法被import到test.py中(加入到__all__就可以)
在test.py中:
from test2 import *
print(num1)
print(num2)
print(num3) # 报错,没有在__all__中
print(_num4) # 报错,私有变量无法被直接导入使用
导入模块底层做的事:
在other.py中:
num = 1
print("执行other")
def run():
print(num)
当test.py中import other.py的时候,会执行other.py的代码;当import了多次other.py时,也只会执行一次该文件;如果执行from other import num也会将other.py全部执行一遍(对应结论的第二点,两种导入方式表示import导入和from … import导入)
模块检索路径:
第一次导入模块:先从级数高的找,即先找内置模块,然后找sys.path列表中的模块
第二次导入模块:
局部导入:
# 当other.py中只有一点内容会被当前文件使用,并且加载other.py文件时间很长,如果直接import在函数外面,会导致资源浪费
def run():
import other
print(other.num)
覆盖导入:
-
当自定义的模块和非内置模块重名(第二级的sys.path),根据前者的储存位置,前者可能会覆盖后者,所以自定义模块不要和后者重名
-
当自定义模块和内置模块重名,内置模块必定覆盖自定义的,此时使用from 自定义模块的绝对路径(即模块所在的包) import 自定义模块
循环导入:
test.py中import了other.py,同样other.py中import了test.py
tips:import了test后,在内存创建的test部分是可以直接用的,不是等到test.py全部执行完毕才能取test那部分内存的东西
可选导入:
两个模块/包功能相近,优先导入一个,另一个作为备选,使用try-catch即可:
# 为了统一,加上相同的别名
try:
import test as t
except ModuleNotFoundError:
import test1 as t
包内导入:
文件目录如下:
在test.py中:
# 绝对导入
import p1.tool1
import sys
print(sys.path)
在tool1.py中:
import tool2
执行test.py时候会报错,因为执行test.py后sys.path的当前路径是dir_test,因为import了p1.tool1,所以需要去执行tool1.py,在执行tool1.py时,需要import tool2,但是由于此时的路径时dir_test,找不到p1下面的tool2.py,所以报错
如果tool1.py改为:
from p1 import tool2
# 相对导入
from . import tool2
上面情况不会报错,因为在dir_test下面有p1文件夹
绝对导入和相对导入:
参考视频:https://www.bilibili.com/video/BV194411r7a8