绝对路径
如下结构:
1 | --__init__.py |
python3导入路径是从哪里读取的?是从sys.path。以打印一下,这里我因为知道结果是一个list,因此for循环遍历打印,看的清晰一些
1 | paths = sys.path |
结果(pycharm中):
1 | D:\Python Project\TopPath |
可以看到,范围有如下目录:
- 运行文件的当前目录(TopPath\dao)
- 当前文件的顶层目录(TopPath)
- python内置模块的目录
- python安装的第三方模块目录
- PyCharm工具的的目录
因此,在import模块的时候,我们可以直接import sys,time这些内置模块或者import requests这样的第三方库。
如果a.py想调用b.py中的方法,需要from dao.b.py import func 如果a.py想调用c.py中的方法,需要from common.c.py import func 如果run.py想调用a.py中的方法,需要from dao.a.py import func
以上需要满足两个条件:
- dao,common都是作为package而存在,其目录下包含init.py
- 代码调用从最顶层目录开始,这里就是从run.py开始,否则会报一系列module不存在的问题
上面第2点,在pycharm中没有问题,回到前面打印sys.path的第二条,可以看到包含了dao层的上层目录(也就是最顶层目录),而在cmd或者如vscode,sublime,atom中的命令行执行,如下
1 | 'D:\Program Files\Python3.6.2\python36.zip', |
可以看到,并没有包含dao目录的上一层!若执行python a.py, b.py会报”No module named xxx”的问题,因为当前环境变量中没有上层目录,只有当前目录如dao, 再写dao.b.py ,无法识别,dao目录下没有dao !!!
嗯,这是大坑,有时候在pycharm中没问题,在命令行就发生包引用报错的情况,不妨打印一下sys.path对比下。以上是绝对路径的引用,import a或者from a import b,会拿a跟环境变量中目录拼接起来去匹配,因此都算是绝对路径。
相对路径的使用呢,跟Linux类似,即 . 表示当前目录,.. 表示上层目录。遵循的原则跟上面类似,同样需要从最顶层调用,否则会报诸如”ModuleNotFoundError: No module named ‘main.collate’; ‘main‘ is not a package”的错。而这次,在pycharm中也无法单独针对一个模块下的文件去执行了,只有从最顶层目录去执行。
最后还有一坑,就是最顶层目录是会变的,现在一般都用pycharm,那么你打开目录的时候最好就是打开要写的那么目录,而不要把上层目录包含进去。例如你有一个文件夹叫test里面有两个工程:pythonproject1和pythonproject2
1 | -- pythonproject1 |
你想修改pythonproject1,那么pycharm 在open 打开目录的时候就选择pythonproject1即可,不要去选test目录,否则你最顶的目录就变成了test。