模块的搜索路径
一、模块搜索路径的顺序
模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径(某个文件夹)。如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。
模块的搜索路径指的就是在导入模块时需要检索的文件夹。
导入模块时查找模块的顺序是:
先从内存中,已经存在的模块中查找
内置的模块
自定义模块
环境变量sys.path中找
import sys print(f"sys.path: {sys.path}") ''' ['/Users/mac/Desktop/video/python/day16', '/Users/mac/Desktop/video/python', '/Applications/anaconda3/lib/python36.zip', '/Applications/anaconda3/lib/python3.6', '/Applications/anaconda3/lib/python3.6/lib-dynload', '/Applications/anaconda3/lib/python3.6/site-packages', '/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend'] '''
强调:sys.path的第一个值是当前执行文件的所在的文件夹
二、验证先从内心中找
如果我们在运行run.py文件的时候,快速删除mmm.py文件,我们会发现文件会继续运行,而不会报错,因为mmm已经被导入内存当中。如果我们再一次运行run.py时会报错,因为mmm.py已经被删除了。
# mmm.py
def f1():
print('from mmm.py f1')
# run.py
import time
import mmm
time.sleep(10)
import mmm
mmm.f1() # from mmm.py f1
三、验证先从内置中找
# time.py
print('from time.py')
# run.py
import time
print(time) # <module 'time' (built-in)>
三、从自定制中找
# m1
x = "m1"
import m1
print(m1.x)
结果:m1
四、从环境变量中找
如果mmm.py在/Users/mac/Desktop/video/python
路径下,而执行文件路径为/Users/mac/Desktop/video/python/day16
,如果普通导入一定会报错,我们可以把/Users/mac/Desktop/video/python
添加到环境变量sys.path中,防止报错。
(主要记住未来项目的执行文件一定要弄一个环境变量)
# run.py
import sys
sys.path.append(r'/Users/mac/Desktop/video/python')
print(sys.path)
import mmm
mmm.f1()
五、python文件的两种用途
编写好的一个python文件可以有两种用途:
一:脚本,一个文件就是整个程序,用来被执行
二:模块,文件中存放着一堆功能,用来被导入使用python为我们内置了全局变量__name__,
当文件被当做脚本执行时:name 等于'main'
当文件被当做模块导入时:__name__等于模块名作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
if name == 'main':直观理解:
对于当前运行的程序test.py而言,name 变量的值是"main"。
如果run.py调用了test.py,即import test,那么对test.py而言name变量的值是"test",对于run.py而言name变量的值是"main"。
背后原因:
有时我们写了可以直接被执行的模块(.py文件),但是在另一个程序中调用它时,我们其实只是想用一用里面写好的函数,而不是全都执行一遍。那么我们就可以把执行的部分放到if name == 'main' 中进行判断。
如果if name == 'main' 为真,就说明我们是在直接执行这个模块,那么所有的操作都要运行一遍;但如果为假,就说明我们是引用了这个模块,只有在需要用到它的函数时,才会被调用执行。
x = 1
def f1():
print('from f1')
def f2():
print('from f2')
f1()
f2()
如果直接运行run.py会直接运行aaa.py中的f1()和f2(),但是如果我们在aaa.py中加上if name == 'main':这句话,则可以防止运行run.py时执行f1()和f2()。因为当aaa.py被直接执行,即当做执行文件的时候__name__ == 'main'; 在aaa.py被当做模块直接运行的时候__name__ == 'aaa'。由此可以让aaa.py在不同的场景下有着不同的用法。
# aaa.py
x = 1
def f1():
print('from f1')
def f2():
print('from f2')
if __name__ == '__main__':
f1()
f2()