【遇见Python】模块 & 包管理 一些冷门知识点(Part I)

129 阅读2分钟

引文

写习惯了js的包引用,虽然都是解释型语言,在python这里,直接用相对路径引用,是会报错的。

从一个Bug说起:

文件

image.png

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文件即可。

image.png

修改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 天,点击查看活动详情