对python的import机制一直停留在import,from 。。 import可以用上。但是一旦项目结构变得复杂就import不对了,各种报错。尤其是被pycharm自动路径管理惯坏了以后,在命令行里跑,import太乱了。。。
比如在一个项目中,结构如下:这是用pycharm管理的一个项目。用pycharm执行脚本和在命令行里执行,import会有不同的行为,因为pycharm会自动加入项目的路径。之后的记录都是用命令行的,因为这个更一般。而且命令行的import能用,pycharm也能用。
首先记录一些常见的术语:
- module:模块,一般一个py文件就是一个模块。
- package:包,含有多个模块的文件夹,当一个文件夹下有__init__.py,这个文件夹就会被识别为一个包。import官方的那个东西也是包,比如import time。
还有一直疑惑的点:
- import的路径有哪些:当前文件的路径和系统库、第三方库等的路径。可以用print(sys.path)查看。在这个例子中命令行执行的结果就是如下图。如果是pycharm的话,还会多一个'G:\\test',也就是项目根路径。
- 路径是按照命令行执行时的路径还是脚本所在的路径:脚本所在的路径。在不同的路径下执行,sys.path的结果都一样。在主文件中调用的其他py文件也是按照主文件的路径。特殊一点的,如果是用bash文件执行py文件,从哪个路径执行这个bash文件都无所谓,还是只看py文件的路径。但是在其他的应用中,比如如果是用open('hhh.txt')是和命令行执行的路径有关的。。。
- python -m file.py可以将文件作为模块执行。可以将上一点中的脚本所在路径替换为命令执行的路径。
如果是import同路径下的文件很容易,直接import就好了。但是想要import 父文件夹或者兄弟文件夹下的模块,就需要额外加入他们的路径。如果我在module_bar.py中直接引用test_utils中的函数是会报找不到的错误。
from utils.test_utils import h
h()
Traceback (most recent call last):
File ".\mypackage\module_bar.py", line 22, in <module>
from utils.test_utils import h
ModuleNotFoundError: No module named 'utils'
所以就用如下代码
import sys
import os
cur_file_path=os.path.realpath(__file__)
cur_directory=os.path.dirname(cur_file_path)
sys.path.append(os.path.join(cur_directory, '..'))
print(sys.path)
from utils.test_utils import h
h()
就可以成功输出结果了。
另外,这里用的是找根目录绝对路径的方式来import其他文件夹下的模块,其实和pycharm自动处理加的路径道理是一样的。不过有的地方说可以加相对路径,但是我尝试以后发现不行。
sys.path.append("..")