1.入口文件不能用相对路径引入模块和包python
所谓的入口文件,就是你须要执行的脚本文件。编程
文件架构以下:vim
---mother_dir ---from_test_dir ---tools_dir ---__init__.py ---demo.py ---__init__.py ---index.py ---__init__.py
上面_dir后缀的名字,都是python package模块名。架构
在如上的文件架构中假设index.py是入口文件,也就是咱们须要执行的脚本,咱们以index.py为起点,去引入demo.py代码以下:app
from .tools_dir.demo import func func()
再附上demo文件代码:ide
def func(): print("hello")
报错信息以下:spa
Traceback (most recent call last): File "D:/lmj_work_file/lmj/from_dir/from_test/index.py", line 31, in <module> from .tool.xxx import func ModuleNotFoundError: No module named '__main__.tool'; '__main__' is not a package
纠错以下:命令行
from tool.demo import func func()
只须要把indexx.py文件中的相对引入换成绝对路径引入便可。code
补充说明另外这里须要提示一点的是,若是是用pycharm这个ide写代码,那么,pycharm它自己默认的东西仍是比较多的,提供了方便的同时,也提供了限制。好比这里模块引入的时候,如上的状况,咱们纠错了,用pycharm能够运行,用命令行也能执行,可是在pycharm里面,blog
它会飘红提示,这里的缘由,我稍微解释一下,pycharm默认,全部的入口文件都须要放到顶层路径下,所谓的顶层路径,就拿以上结构来讲,最外层的文件夹名字是mother_dir它下面的一级路径就是顶层路径,也就是说咱们把以上的项目结构改为以下的样子:
---mother_dir ---from_test_dir ---tools_dir ---__init__.py ---demo.py ---__init__.py ---__init__.py ---index.py
咱们把index.py文件从from_test_dir包里面拿出来放到了monther_dir包里面,做为它的子文件,此时,咱们的模块引入就不会在pycharm中有飘红提示了。
或者写成这样也能够:
from from_test.tool.xxx import func
func()
也不会飘红提示。
2,相对导入方法处理这里之因此会写这篇博客是由于我要把我写的脚本放到一个文件夹下面,便于管理,可是在这个过程当中,有一些公共方法,我须要在脚本中互相引入,这些方法也跟脚本在同一个母文件路径下,此时的引入就出现问题。结构以下示例:
---mother_dir ---from_test_dir ---tools_dir ---__init__.py ---demo.py ---__init__.py ---index.py ---to_test_dir ---__init__.py ---test.py ---__init__.py
仍是把index做为入口文件,咱们要从index.py中导入to_test_dir这个包里面的test.py文件中的内容。在index中的代码以下写:
from ..to_test.lala import test_func
test_func()
报错信息以下:
ValueError: attempted relative import beyond top-level package
这里纠错,用绝对路径导入,把相对路径改为绝对路径。
from to_test.lala import test_func test_func()
便可运行pycharm。
可是在命令行运行的时候,会抛错:
ModuleNotFoundError: No module named 'to_test'
当咱们的ide和命令行的运行结构有歧义的时候,必定要解决命令行的问题,这也就是为何不少大佬不用ide,只用vim编程的缘由,快,尚未这么多衍生的问题。
我写这篇博客核心要解决的就是这个问题
import os import sys DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(DIR)
from to_test.lala import test_func
test_func()
把上面这段粘回去就能用了。命令行运行正常。
你想知道为何吗?
我也不知道,本身去看源码吧,或者尝试print一些中间结果看看