gpt4 book ai didi

python - 从外部调用时找不到模块

转载 作者:太空狗 更新时间:2023-10-30 00:09:10 25 4
gpt4 key购买 nike

我有一个多个子模块 python 项目。例如,“myproject”有两个子模块,即“submodule1”和“submodule2”。

项目结构

Example1/
|-- submodule1/
| |-- __init__.py
| |-- hello.py
...
|-- submodule2/
| |-- __init__.py
...

我有一个 hello.pysubmodule1其中有以下内容:
import datetime

def greeting():
print("hello world! - " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
submodule1的内容的 __init__.py是:
def main():
import hello
hello.greeting()

if __name__ == '__main__':
main()

我可以导入 hello.py并调用 greeting()在这里成功运行。

现在,我安装了 submodule1作为一个包到python,然后创建 submodule2 ,并尝试拨打 submodule1来自 submodule2通过将以下代码放入 __init__.py来自 submodule2 :
import submodule1

def main():
submodule1.main()

if __name__ == '__main__':
main()

它失败并显示以下消息:
....in main submodule1.main()
ModuleNotFoundError: No module named 'hello'

我想 hello不应该暴露在外面,我怎么能让我的 submodule1作品?我正在使用 python3

========

setup.py 是:
from setuptools import setup, find_packages

with open('requirements.txt') as f:
requirements = f.read().splitlines()

__version__ = "0.0.2"

setup(
version=__version__
name = "mymodules",
packages = find_packages(exclude=['tests', '*.tests', '*.tests.*']),
install_requires=requirements,
)

最佳答案


def main():
from .submodule1 import hello
# or from Example1.submodule1 import hello
hello.greeting()

if __name__ == '__main__':
main()

没有找到 hello因为它不在 submodule2文件夹。您必须为解释器提供包内的相对路径,或包中的绝对路径。这仅适用于 from ...导入语法形式。

如果您有大量导入并且稍后想要更改您的包名称,则省略包名称会很有用。

编辑:

这是从 Example1里面的代码来看的包,如果你把它变成一个。也就是这个包 Example1里面的代码方式, 在某些子模块中,可以引用其他 Example1 中的代码子模块,子模块放置在不同的文件夹中,也带有 __init__.py里面。这是内幕知识,但要从包内使用 Example1 .外出时,导入包 Example1 , 你可以在 Example1 __init__.py 中导入所有你想从外部(在导入器中)看到的名字文件。

所以我在这里看到两个不同的问题:

我如何将代码从子模块引用到子模块,两者都在同一个包内(就像我说的那样),以及我如何将包内的名称导出给导入我的包的外部人员(导入包中的名称 _init__.py 所以你可以写出诸如 from MyPackage import Class1, Class2, other_name 甚至 * 之类的东西 - 使用 __all__ 列表来控制这些名称)。

此外,我不明白为什么您将子模块称为子模块,然后尝试将其中一个安装为隔离包并像这样使用它。它们不是您的 Example1 的一部分吗?包裹?如果它们是孤立的包,则不应引用其他包...

像这样说,这可能看起来很困惑,实际上包不是最容易解释的概念,但也不是那么难。

查看我制作的干净示例 here关于如何将类组织为一个包并在包内使用它们(当然是内部知识)。关注 __init__.py文件内容,因为它类似于您想要在包外提供名称的操作(除了可导入的名称外,没有内部知识)。

第二次编辑:

因此,我将我和 OP 之间的一些混淆来源追溯到:
我上面说的一切都适用于 import packages而 OP 正在考虑 distribution packages .毫不奇怪,即使是词汇表也将这种混淆称为真实的可能性。

你试过了吗
from . import hello

submodule1导入包 __init__.py , 而不是 import hello ?那应该使用 submodule1命名空间。

第三次编辑:

您的错误可能会发生,因为在设置导入后,运行是否成功仍然取决于您如何运行代码(我的意思是从哪里导入整个内容),这通常是包父文件夹。如果您尝试从内部开始代码,尽管它是正确的,它仍然可能会失败(对不起,语无伦次)。

即使这可以通过绝对导入来解决,但这需要 Example1 成为一个包,因为您在子模块(实际上是子包)之间存在依赖关系。

这让我想到了另一点:

一个导入包可以包含嵌套的导入包(子包),也可以包含模块。这使它适用于任何项目。这意味着还有一个包含所有内容的外包装。那是你的项目。发布该外部包,即您的项目。

假设您说“必须单独安装子模块”。美好的。假设它们是独立的,将它们打包(它们已经是包)。如上所述分别释放它们。

或者,

对我来说,它们看起来相关,看起来有些“子模块”依赖于其他模块。

您还说“下面的子模块可以由不同的开发人员响应”。那不是借口。在我看来,它是一个通用的代码库,将它们全部置于版本控制中(您做到了,不是吗)。在发布点中标记文件,或将发布放在它们自己的分支中。把它全部做成一个包。释放那个包。

否则我认为你是在制造困惑。而你正试图使用​​发布包来控制它。您如何记录哪个版本适用于另一个子模块的哪个版本。如果您将不同子模块的源放在一起进行测试,它们将与系统中先前安装的子模块发生冲突(覆盖)。

此外,您的包将有一个入口点,要么是简单的导入,要么是一些主钩子(Hook)来运行主函数,而不是来自每个“子模块”的几个可能的入口点。

我希望这有助于解决您的问题,而不是您的错误。

关于python - 从外部调用时找不到模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48890084/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com