引文
写习惯了js的包引用,虽然都是解释型语言,在python这里,直接用相对路径引用,是会报错的。
从一个Bug说起:
文件
main.py文件内容:
from . import import_me
if __name__ == '__main__':
import_me.demo()
import_me.py文件内容:
def demo():
print('demo')
报错
直接运行main.py报错
Traceback (most recent call last):
File "C:\Users\...\lib\site-packages\IPython\core\interactiveshell.py", line 3442, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-9f7288d147f1>", line 1, in <module>
runfile('D:/Work/Code/.../import_demo/main.py', wdir='D:/Work/Code/.../import_demo')
File "D:\Work\Dev\PyCharm 2021.2.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 198, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "D:\Work\Dev\PyCharm 2021.2.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "D:/Work/Code/.../import_demo/main.py", line 2, in <module>
from . import import_me
File "D:\Work\Dev\PyCharm 2021.2.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_import_hook.py", line 21, in do_import
module = self._system_import(name, *args, **kwargs)
ImportError: attempted relative import with no known parent package
分析 & 解决
"ImportError: attempted relative import with no known parent package"是一个常见的Python导入错误。这意味着,您正在尝试使用相对导入而不是绝对导入,但Python无法找到相对导入的父包。
网上查到的很多解决方案,都是教我们通过修改sys.path来解决这个问题。但是问题的本质,其实是在项目结构设计上:我们试图用扁平结构来组织文件的同时,试图把要实现的函数,分割到两个文件中去。
解法一:直接Import
修改main.py
import import_me
if __name__ == '__main__':
import_me.demo()
发现,直接run就不会报错了。
解法二:新建一个包
如果你要创建一个单独的文件来做有用的事情,为什么不把它做成一个实际的包呢?
新建一个包其实非常非常容易:只需要更改文件结构,把想要分离出的函数,放到单独的文件夹中,并包含一个空的__init__.py文件即可。
修改main.py
from import_me import import_me
if __name__ == '__main__':
import_me.demo()
于是又可以运行啦。
挖坑
下一篇,我们会详细分析下,为什么这么写可以解决报错问题,以及为什么会报错。
下一篇再见~~
参考文献
ImportError: attempted relative import with no known parent package (iq-inc.com)
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情