从兄弟目录导入 Python class

Importing Python class from sibling directory

我在 /VM/repo/project 中的目录结构是:

__init__.py

scripts/
      getSomething.py
      __init__.py

classes/
      project.py
      db.py
      __init__.py

getSomething.py

from ..classes import project
from ..classes import db

project.py

class PROJECT:
def __init__(self):
    stuff

db.py

class DB:
def __init__(self):
    stuff

当我尝试 运行

python getSomething.py

我收到错误

Traceback (most recent call last):
File "scripts/getSomething.py", line 4, in < module >
from ..classes import project
ValueError: Attempted relative import in non-package

我在这里错过了什么?

如错误中所述,您 运行宁 getSomething 作为主模块。但是当你不在一个包中时,你不能做包相关导入。主模块从不在包中。因此,如果您要将 getSomething 作为包的一部分导入...:[=​​25=]

# /VM/repo/main.py
from project.scripts import getSomething

这样就不会出现导入错误了。


快速讨论 python 模块和包可能会有所帮助。通常,包含 python 源代码并具有 .py 扩展名的文件是一个模块。通常该模块的名称是文件的名称(无扩展名),但如果您直接 运行 它,则该模块的名称是 '__main__'。到目前为止,这都是众所周知的并有据可查。要导入模块,您只需执行 import moduleimport package.module 等等。最后一个导入语句指的是我们现在要讨论的其他内容("package")...

包是您可以导入的目录。许多目录无法导入(例如,它们可能没有 python 源文件 -- 模块 -- 其中)。所以要解决这个歧义,还有一个要求就是目录要有一个__init__.py文件。当您在文件系统上导入目录时,python 实际上会导入 __init__.py 模块并从 __init__.py 中的内容创建相关包(如果有的话)。

将所有这些放在一起说明了为什么在具有 __init__.py 的目录中执行文件不足以让 python 将模块视为包的一部分。首先,模块的名称是__main__,而不是package.filename_sans_extension。其次,包的创建不仅取决于文件系统结构,还取决于目录(因此 __init__.py 是否实际导入)。

您可能会问自己 "Why did they design it this way?" 事实上,我有时也问过自己同样的问题。我认为这是因为语言设计者希望为包提供某些保证。包应该是为特定目的而设计的一组事物。它不应该是一个脚本孤岛,凭借一些随意的 __init__.py 文件获得在文件系统中走动以找到他们需要的其他模块的能力。如果某些东西被设计成 运行 作为主模块,那么它可能不应该是包的一部分。相反,它应该是一个单独的模块,导入包并依赖它。