如何在 Python 中从同级目录导入模块

3
作为问题,我有一个像这样的目录地图

enter image description here

enter image description here

formatOutput包含一些用于更好打印的函数。现在,我想在findInfoSystem.py中使用位于formatOutput包中printChecked.py模块中的一个函数。

我已经尝试在所有文件夹中创建__init__.py来让Python将其视为一个包(这是我从另一个帖子的先前答案中获得的建议),但它总是失败。

情况1:from formatOutput.printChecked import print_checked_box

错误信息为:ModuleNotFoundError: No module named 'formatOutput'

情况2:from dttn.formatOutput.printChecked import print_checked_box

错误信息为:ModuleNotFoundError: No module named 'dttn'

情况3:from ..formatOutput.printChecked import print_checked_box

错误信息为:ImportError: attempted relative import with no known parent package

我不想使用sys.path方法,因为我认为这不是解决问题的好方法。

请帮帮我!


你尝试在哪个文件中导入它?这可能会改变一切。我认为 sys.path 可能是最好的方法。 - furas
@furas 我试图将printChecked.py导入到findInfoSystem.py中。我现在正在使用sys.path作为替代方法,但据我所知,这是一种代码异味。这个项目对我来说非常重要,所以我想让它最好地工作。 - Thanh Tuấn Lê
我个人认为formatOutputmodule1就像两个不同的模块,使用sys.path似乎是最好的方法。 - furas
2个回答

1
我发现了一些非常奇怪的事情。在模块文件中,我没有直接导入,而是从包的__init__.py文件中导入,然后从包名导入到模块文件中,它竟然可以工作。就像这样:
systemInfo包的__init__.py中:
import sys,os
from formatOutput import prettyAnnounce,prettyParseData
current_directory = os.getcwd() 
# sys.path.insert(1, current_directory+"/formatOutput/")
# sys.path.insert(1,current_directory+"/")

然后在findInfoSystem.py模块中,我再次像这样导入:

from systemInfo import current_directory, prettyAnnounce as prCh , prettyParseData as prPD

是的,现在它能完美地运行。:))) 我甚至不确定怎么做到的。


0

解决这个问题有两种方法:

  1. 修改Python导入路径

  2. 使用各种设置工具或手动安装.egg-link或符号链接,以“安装”你的开发模块在python/lib/site-packages中

第一种方法很简单,但第二种方法需要深入了解许多相关主题。你可能需要一个虚拟环境和一个setup.py等等。

所以,对于快速而肮脏的方式,有两种修改Python导入路径的方法:

  1. 将PYTHONPATH=环境变量设置为包含您的软件包父目录
  2. 在导入formatOutput.printChecked之前的findInfoSystem中添加以下内容:
import sys
sys.path.append("..")

我现在使用import sys作为替代方法。但是我想找到一个内置的官方方法来使其工作。似乎有点困难。 - Thanh Tuấn Lê
官方方法是编写一个setup.py来安装你的模块。这是一个比较大的主题。https://docs.python.org/3/distributing/index.html - dirck
如果这两个包是相关系统的一部分,它们也可以成为外部包的子包。这会改变导入方式 - 然后您可以使用“..”进行相对导入。 - dirck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接