从同级目录导入Python类
我在从同级目录导入Python类,python,import,module,package,relative-import,Python,Import,Module,Package,Relative Import,我在/VM/repo/project中的目录结构是: __init__.py scripts/ getSomething.py __init__.py classes/ project.py db.py __init__.py 得到一些东西 project.py db.py 当我试着跑的时候 python getSomething.py 我得到了错误 回溯(最近一次呼叫最后一次): 文件“scripts/getSomething
/VM/repo/project
中的目录结构是:
__init__.py
scripts/
getSomething.py
__init__.py
classes/
project.py
db.py
__init__.py
得到一些东西
project.py
db.py
当我试着跑的时候
python getSomething.py
我得到了错误
回溯(最近一次呼叫最后一次):文件“scripts/getSomething.py”,第4行,在
从..类导入项目
ValueError:尝试在非包中进行相对导入
我错过了什么 如错误中所述,您正在作为主模块运行
getSomething
。但是,当您不在包中时,不能进行包相对导入。主模块从不在包中。因此,如果要将getSomething
作为包的一部分导入…:
# /VM/repo/main.py
from project.scripts import getSomething
这样就不会出现导入错误
快速讨论python模块和包可能会有所帮助。通常,包含python源代码且扩展名为
.py
的文件是一个模块。通常,该模块的名称是文件名(SAN扩展名),但如果直接运行该模块,则该模块的名称是“\uuuuu main\uuuuu”
。到目前为止,这一切都是众所周知的和有记录的。要导入模块,只需执行导入模块
或导入包.module
等操作。最后一个导入语句引用了我们现在要讨论的其他内容(“包”)
包是可以导入的目录。许多目录无法导入(例如,它们可能没有python源文件——模块)。因此,为了解决这种模糊性,还需要目录有一个\uuuu init\uuuu.py
文件。当您在文件系统上导入目录时,python实际上会导入\uuuu init\uuuuuuuuuuuuuupy
模块,并从\uuuuu init\uuuuuuuuuuuuuuuuupy
中的内容创建关联的包(如果有)
将所有这些放在一起,说明了为什么在一个目录中执行一个文件,该目录中有一个<代码> *iNITSy.Py</Copy>不足以让Python考虑模块是包的一部分。首先,模块的名称是
\uuuu main\uuu
,而不是包.filename\u sans\u扩展名
。其次,包的创建不仅取决于文件系统结构,还取决于目录(因此\uuuu init\uuuuu.py
是否实际导入)
你可能会问自己“他们为什么这样设计?”事实上,我有时也会问自己同样的问题。我认为原因在于语言设计者希望为包提供某些保证。一个包应该是为特定目的而设计的一个事物单元。它不应该是一个由脚本组成的筒仓,通过几个随意的
\uuuu init\uuuu.py
文件,它可以在文件系统中找到它们需要的其他模块。如果某些东西被设计为作为主模块运行,那么它可能不应该是包的一部分。相反,它应该是一个单独的模块,导入包并依赖于它。好的,有几件事:我的印象是,向每个目录添加\uuuu init\uuuuuuuuuupy
基本上将这些目录定义为一个包?我可能对这里的包有一个基本的误解。为什么主模块从不在包中?第二:我的目标是在cron上运行脚本。没有办法直接将类导入脚本中吗?创建另一个文件main.py
再上一层对我来说似乎是不必要的麻烦。@ShaneOH--我已经尽力编辑我的答案,希望能消除任何歧义。。。我希望有帮助。谢谢,原始答案和编辑都非常有用。所以我还有最后一个问题:如果我想保持这个目录结构并直接运行脚本,作为主要模块,该怎么办?所以,好吧,他们不需要成为一揽子计划的一部分。如何将/classes模块导入同级文件夹中的主模块?然后我是否从/scripts和/project中删除\uuu init\uuuuuuuuuupy
?您可以将path/to/project
添加到PYTHONPATH
。然后脚本应该能够从文件系统中的任何位置导入project.class.xyz
。明白了。不幸的是,这一切似乎如此不直观,但我能理解你所描述的优点。再次感谢!
class PROJECT:
def __init__(self):
stuff
class DB:
def __init__(self):
stuff
# /VM/repo/main.py
from project.scripts import getSomething