本文已参与「新人创作礼」活动,一起开启掘金创作之路。
python import
sys.path存储了导入时可搜索的路径
ref
ModuleNotFoundError: No module named 'main.xxx'; 'main' is not a package问题
Python 3.x | 史上最详解的 导入(import)
导入规则
一些基础概念:
- pkg:包含
__init__.py的目录,放了很多xx.py - module:
xx.py文件 - class、func、var等等
模块内置属性:
- name 模块名字。 name == __main__时,直接运行本模块。
- file 当前 module的绝对路径
- dict
- doc
- package
- path
搜索路径:
导入时,会从sys.path提供的路径中搜索要导入的东西
重要的是,sys.path会根据你执行python xxx.py和启动jupyter notebook的所在目录,把这个目录加到sys.path中。
-
在工程根目录下启动
jupyter notebook时,会自动添加..../project_root/src到sys.path中- 在pycharm下直接启动
jupyter notebook时,会添加运行的ipynb文件所在目录和工程根目录
- 在pycharm下直接启动
-
其他情况
-
最好对于上一级或者上两级的目录直接
sys.path.append([".."]),它接收list。
一些路径操作:
import sys,os
os.path.abspath(__file__) #获取当前文件的全名
os.path.dirname() #获取当前对象的父级目录
os.chdir() #用于指定当工作目录
sys.path.insert()#将当前对象的路径添加到首位
sys.path.append() # 将当前环境变量添加到环境变量的末尾
可行方法:
以src为根目录,从src的下一级目录开始导入,每次都是从src的下一级开始,即绝对导入
文件结构:
|---src
|---Core
|---__init__.py
|---Wheel.py
|---Parser.py
from Core.Wheel import Wheel
pycharm运行正常命令行运行报错
注意事项:
这样只能在pycharm中可以运行,在命令行中会报错:
ModuleNotFoundError: No module named 'practice'
原因:
观察pycharm的python console可以看到,在运行之前,pycharm添加了代码:
sys.path.extend(['/home/pbc/Documents/PycharmProjects/myEPI/src', ])
即,将工程根目录路径和source root路径添加到了系统路径
经实验,src路径是有效的起作用的,根目录不起作用
解决方法:
把src路径添加到系统路径
# sys.path.extend(['/home/pbc/Documents/PycharmProjects/myEPI', '/home/pbc/Documents/PycharmProjects/myEPI/src'])
# sys.path.extend(['/home/pbc/Documents/PycharmProjects/myEPI', ])
sys.path.extend(['/home/pbc/Documents/PycharmProjects/myEPI/src', ])
工作目录(wdir,cwd)
work directory
current work dorectory
当前所运行python文件所在的目录,
这个在CLI和pycharm中是一致的
import os
print(os.getcwd())
几种导入的常见使用
使用同目录下的module,做导入时:
-
将目录变为包的形式(就是增加一个
__init__.py文件) -
在
__init__.py中导入所有module中建议给外部使用的from .xx_module import xx,xxx,... -
这样,在与同包同级的
py文件中导入,可以直接跨过module,只要写:from xx_pkg import xx,xxx,...
主动添加src目录和工程根目录:
import sys
import os
_current_path = os.path.dirname(__file__)
sys.path.extend([os.path.join(_current_path, "../../../myPro")])
sys.path.extend([os.path.join(_current_path, "../../src")])
print(sys.path)
\