Sha*_*eOH 2 python import module package relative-import
我花了过去一小时的时间来浏览Google和SO.很抱歉添加另一个,但没有一个答案对我有用.
我的目录结构/VM/repo/project
是:
__init__.py
scripts/
getSomething.py
__init__.py
classes/
project.py
db.py
__init__.py
Run Code Online (Sandbox Code Playgroud)
====================
getSomething.py
from ..classes import project
from ..classes import db
Run Code Online (Sandbox Code Playgroud)
====================
project.py
class PROJECT:
def __init__(self):
stuff
Run Code Online (Sandbox Code Playgroud)
====================
db.py
class DB:
def __init__(self):
stuff
Run Code Online (Sandbox Code Playgroud)
====================
当我试图跑
python getSomething.py
我收到了错误
Traceback(最近一次调用最后一次):
在<module>中的文件"scripts/getSomething.py",第4行
来自..classes导入项目
ValueError:在非包中尝试相对导入
我在这里错过了什么?
如错误中所述,您将getSomething
作为主模块运行.但是当你不在包中时,你不能打包相对导入.主模块永远不在包中.所以,如果您要getSomething
作为包的一部分导入...:
# /VM/repo/main.py
from project.scripts import getSomething
Run Code Online (Sandbox Code Playgroud)
那你就不会有导入错误.
或许对python模块和包进行快速讨论会很有帮助.通常,包含python源代码并具有.py
扩展名的文件是一个模块.通常,该模块的名称是文件的名称(无扩展名),但如果直接运行,则该模块的名称为'__main__'
.到目前为止,这一切都是众所周知和记录在案的.要导入你只是做一个模块import module
或import package.module
等等.最后一个import语句引用了我们现在要讨论的其他东西("包")......
包是您可以导入的目录.许多目录无法导入(例如,他们可能没有python源文件 - 模块 - 在其中).因此,为了解决这种歧义,还要求目录具有__init__.py
文件.当您在文件系统上导入目录时,python实际上会导入__init__.py
模块并从中的内容创建关联的包__init__.py
(如果有的话).
将所有这些放在一起说明了为什么在一个目录中执行一个文件__init__.py
是不够的,python认为该模块是一个包的一部分.首先,模块的名称__main__
不是package.filename_sans_extension
.其次,一个包的创建不仅依赖于文件系统的结构,但是否该目录(因此__init__.py
实际上进口).
你可能会问自己"为什么他们这样设计呢?" 实际上,我偶尔会问自己同样的问题.我认为原因是语言设计者希望对包装有一定的保证.包装应该是为特定目的而共同工作的单元.它不应该是一个脚本的孤岛,凭借一些偶然的__init__.py
文件获得了遍历文件系统以找到他们需要的其他模块的能力.如果某些东西被设计为作为主模块运行,那么它可能不应该是包的一部分.相反,它应该是一个单独的模块,导入包并依赖它.