关于“. metrics”中“.”
来源:4-4 分类准确度
慕函数6301763
2022-11-25
关于在kNN.py中增加score函数的问题
在前面加上 " from .metrics import accuracy_score " ,在pyCharm中点运行,提示
“C:\Users\yanji\anaconda3\python.exe D:\JupyterNotebook_32\MachinaLearning\playML\kNN.py
Traceback (most recent call last):
File “D:\JupyterNotebook_32\MachinaLearning\playML\kNN.py”, line 4, in
from .metrics import accuracy_score
ImportError: attempted relative import with no known parent package
Process finished with exit code 1”
如果将from .metrics 中的“.” 去掉,则能运行正常,但是在Jupyternote中调用时就报错了,加上“.” 虽然pycharm运行失败,但是在Jupyternote中调用能正常运行
为什么??
1回答
-
简单来说,你不应该在包(package)内运行包自身(执行 __main__ 就是运行),而应该在包外做执行,包的意义是封装一系列的函数和方法,供包外的文件执行,而不是在包内部自己执行自己。
Jupyter Notebook 就是一个外部的执行,可以参考在这个答案下,我给出的对课程目录结构的说明:https://coding.imooc.com/learn/questiondetail/4daeRY43bz0PnWEp.html
即使不使用 Jupyter Notebook,也是如此,比如一个典型的 py 工程的结构大概是这个样子:
==========
如果你要对背后的机制感兴趣(为什么),简单说明如下:
使用 .metrics,为什么在包内的 __main__ 下执行就报错?PEP 338 给出了完整的说明:https://peps.python.org/pep-0338/
我把关键点截图如下:
简单来说,__main__ 是一个特殊的运行环境,被称为是 top-level enviroment(https://docs.python.org/3/library/__main__.html),当执行在 __main__ 下的时候,当前的脚本没有处在当前的模块的位置,而处在一个特殊的叫做 __main__ 的模块的位置,这个模块的上层没有其他包了,而调用 ,metrics 的意思是,看当前模块的上层的包下面的 metrics 模块,但没有上层的包,所有就有了这个错误:with no known parent package,parent package 就是上层包的意思。
使用 metrics 为什么在包内的 __main__ 下执行没有错?
因为没有点,就没有去找上层的包,此时 import 找寻的 sys,path 的所有路径下是否有对应模块。当前路径在 sys.path 下,而 metrics 在当前路径,所以成功运行。
----------
使用 metrics 为什么在 Jupyter Notebook 下报错了?
此时,因为没有点,import 找寻的 sys,path 的所有路径下是否有对应模块。当前路径在 sys.path 下,而 metrics 不在当前路径,更不在其他系统路径下,所以会报错:模块没有找到。
使用 .metrics 为什么在 Jupyter Notebook 下执行没有错?
这就是 relative import 的意义,此时,将寻找 playML 这个包下 kNN 这个模块的上一层下的所有模块,能找到 metrics 模块,所以成功。
相关 import 的更详细的机制说明,可以参考这里:https://docs.python.org/3/reference/import.html
==========
最后,依然是,不建议在包内执行包自身,包和执行包的脚本应该分开。
对于这一原则,python 的设计师曾明确表示,在包内运行包是 antipattern,不应该这样做。可以参考这里:https://mail.python.org/pipermail/python-3000/2007-April/006793.html
继续加油!:)
212022-12-05
相似问题