Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从同级目录导入Python类_Python_Import_Module_Package_Relative Import - Fatal编程技术网

从同级目录导入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