1.入口文件不能用相对路径引入模块和包
所谓的入口文件,就是你需要执行的脚本文件。
文件架构如下:
---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代码如下:
from .tools_dir.demo import func func()
再附上demo文件代码:
def func(): print("hello")
报错信息如下:
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文件中的相对引入换成绝对路径引入即可。
补充说明另外这里需要提示一点的是,如果是用pycharm这个ide写代码,那么,pycharm它本身默认的东西还是比较多的,提供了方便的同时,也提供了限制。比如这里模块引入的时候,如上的情况,我们纠错了,用pycharm可以运行,用命令行也能执行,但是在pycharm里面,
它会飘红提示,这里的原因,我稍微解释一下,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一些中间结果看看