python - 如何在 python 中处理多个模块/包?

标签 python import module package

我花了几个小时研究这个问题,但仍然感到困惑。请发现我的无知迷人。

我正在构建一个 Python 程序,它允许我在战舰游戏中让两个 AI 相互对抗。

这是我的目录结构:

.
├── ais_play_battleship
│   ├── game.py
│   ├── __init__.py
│   ├── player.py
│   └── ship.py
├── LICENSE
├── README.md
└── tests
    └── ship_test.py

2 directories, 7 files

目前,我正在尝试编写ship_test.py,但我似乎无法导入ais_play_battleship.ship。我收到可怕的“ModuleNotFoundError”

以下是我的研究告诉我的问题:

  • 如果你想从另一个目录导入Python代码,你应该将该目录设置为包而不是模块。因此,我在 ais_play_battleship 的根目录中放置了一个 __init__.py 文件。
  • Python 只会搜索启动 python 的目录以及正在运行的脚本的目录。因此,我一直尝试通过从根目录运行 python3tests/ship_tests.py 来启动测试。

这是我的具体问题:

  • 为什么错误是“ModuleNotFound”错误?不应该是“PackageNotFound”吗?
  • 我将 ais_play_battleship 制作为一个包是否正确?
  • 如何将测试保存在单独的目录中并仍然使用 ais_play_battleship 中的代码?

请原谅我,因为我不太擅长在 StackOverflow 上提问。请告诉我如何改进。

最佳答案

我正在回答我自己的问题,因为我还没有收到满意的答案。我找到的最好的资源是available here 。总结一下:

Python 不会在运行 python 的目录中搜索模块。此外,添加一个 __init__.py 文件来使目录成为包并不足以使其对在另一个文件夹中运行的 python 实例可见。您还必须安装该软件包。因此,访问另一个目录中的模块的唯一方法有两种:

  1. 在 site-packages 中安装打包的模块(这需要创建 setup.py 文件并使用 pip install 进行安装。更多信息是 available here. <
  2. 修改模块解析路径

出于下面讨论的原因,我最终选择了第二个选项。

第一个选项要求在每次更改软件包时重新安装软件包。这对于不断变化的代码库来说很困难,但通过使用构建自动化可以变得更容易。但是,我想避免这种增加的复杂性。

我很长一段时间都回避第二个选项,因为修改路径似乎需要硬编码模块的绝对路径,这显然是 Not Acceptable ,因为每个开发人员都必须编辑该路径以适应他们的环境。然而,this guide提供了这个问题的解决方案。创建一个包含以下内容的 ./tests/context.py 文件:

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

然后,在我的 ship_test.py 模块中,我导入了上下文和我需要的模块:

import context
import ais_play_battleship.ship
# (I include the submodule ship because ais_play_battleship itself does not have
# any attributes or methods, and the submodule ship is the only one I am testing
# in ship_test.py)

这更适合我的项目,因为它按预期工作,而不必担心安装我的包(或安装我的包的方法)。

关于python - 如何在 python 中处理多个模块/包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51776981/

相关文章:

Python 使用 struct 将定界文本文件固定为 csv

javascript - es2015 重新导出模块并覆盖重新导出模块的单个导出功能

javascript - 这两个 node.js 模块做同样的事情吗?

css - 多个 LESS 文件导入嵌套变量和单个 CSS 文件的混合

java - Intellij - JAVA 错误(导入等...)未检测到

Python:模块和打包 - 为什么 __init__.py 文件不在 __main__.py 之前执行?

python - md5模块错误

python - 如何使用 "Client name:"从 python 脚本获取 perforce 工作区的 "p4 info"?

Pythonic 方式来洗牌堆栈

python - 如何将多个字符串传递给Python程序