Python 无法从父目录导入文件
我的文件结构如下:Python 无法从父目录导入文件,python,python-3.x,Python,Python 3.x,我的文件结构如下: monitor/ core/ database.py processor.py timekeeper.py jobs/ jobA.py jobB.py setup.py 从jobA.pyI导入如下内容: from core.database import Database from core.timekeeper import Timekeeper from core.
monitor/
core/
database.py
processor.py
timekeeper.py
jobs/
jobA.py
jobB.py
setup.py
从jobA.py
I导入如下内容:
from core.database import Database
from core.timekeeper import Timekeeper
from core.processor import Processor
在database.py
、processor.py
和timekeeper.py
时,我导入setup.py
运行
jobA.py
时出现以下错误:
root@test:/var/www/python/monitor# python3 jobs/jobA.py
Traceback (most recent call last):
File "jobs/jobA.py", line 2, in <module>
from core.database import Database
ModuleNotFoundError: No module named 'core'
root@test:/var/www/python/monitor#python3 jobs/jobA.py
回溯(最近一次呼叫最后一次):
文件“jobs/jobA.py”,第2行,在
从core.database导入数据库
ModuleNotFoundError:没有名为“core”的模块
您想使用什么模块?可能您的模块与Python 3不兼容。在回答中,您可以使用2个点从上面的目录导入。因此,您可以潜在地使用:
from .core.database import Database
from .core.timekeeper import Timekeeper
from .core.processor import Processor
Python3.3+您不需要\uuu init\uuuu.py
文件,所以我不相信仅仅添加一个文件就可以了。添加
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
到您的
jobA.py
文件的顶部。如果您使用的是python 3.3+,则不需要\uuuu init\uuuu.py
文件。它需要位于其他import
语句之上。若要允许导入核心
或导入核心。数据库
(不带相对点或双点)核心的父目录应为当前目录,或包含在系统路径
中。您似乎有一个setup.py
。通常,这意味着通过setuptools
或distutils
软件包执行安装和打包任务的文件。如果这确实是它所扮演的角色,那么您可能需要运行它。运行它的一种方法是(从Python外部的命令行)发出命令pip install-e/path/to/monitor
。假设setup.py
编写正确,这将确保当前位置的core
包可用于默认Python发行版。下次启动Python时,/path/to/monitor
将处于sys.path
状态,import core
将在(几乎)任何位置工作。您需要将父目录的路径添加到Python路径中。有点奇怪的层次结构,若您计划直接从shell执行它们,为什么要在子目录中创建“作业”?通常应该有启动程序脚本,根据参数启动不同的作业。@OlvinRoght“作业”将由cron执行。@Borsn,实际上并不重要。创建launcher.py
它将从所需的python脚本执行主函数,该脚本执行“job”并按您的需要启动它。@OlvinRoghtlauncher.py
应该放在哪里?错误:回溯(最后一次调用):文件“jobs/jobA.py”,第2行,在from..core.database import database VALUE ERROR:尝试在顶级软件包之外进行相对导入
我的道歉使用了一个点而不是2我编辑了答案。我不完全清楚OP是打算将monitor
作为顶级软件包,还是只包含顶级软件包的目录。如果monitor
被认为是顶级软件包,则两点是正确的,但如果无法访问monitor
软件包,则两点将以此处报告的方式失败(例如,如果当前工作目录是monitor
而不是monitor
的父目录,并且monitor
的父目录不在sys.path
)。不要在您打算成为包的目录中工作。这会导致很多混乱。您在这里假设OP意味着作业目录是包。这里的情况似乎不是这样。@MartijnPieters是的,如果作业目录不是包,它不应该假设包的固定位置rel运行pip安装-e/path/to/monitor
是否会构建monitor
软件包?因此Borsn必须从monitor.core import X构建?我只构建了几个软件包,所以我诚恳地问,根据我的经验,我认为这是如何工作的。另外,考虑有多少软件包使用core
>或者src
或命名其目录的东西…@MasonCaiby,这实际上取决于setup.py
的编写方式。通常情况下,默认情况下,对于setup.py
的位置不作任何假设:setup.py
中的代码必须明确定义哪些包(相对于其自身位置)正在作为打包的目标。顺便提一下,-e
标志意味着实际上没有“构建”任何内容,而是每个目标包的父位置只是添加到路径中(该包被称为“安装为“可编辑”)如果此文件结构是OP自己设计的,core
是否真的打算成为顶级名称,可以从任何地方导入?如果不是,您真的想将其命名为monitor.core
,那么(a)setup.py
应该是监视器
旁边的一个,而不是核心
,并且应该包含安装/构建监视器
包的说明;(b)jobA/jobB应该使用相对导入,但是(c)它们真的应该存在吗?有了这样的通用名称,我想它们是monitor
包的特定用例,而不是可重用的子模块。如果是这样,它们应该位于包之外并导入monitor.core
。如果稍微扩展一下,这个答案就更有意义了,因为它解释了只有Python 3.3+才会尝试处理d没有作为包的\uuuu init\uuuu.py
文件的目录。