我有一个我一直在开发的包,为了让我的脚本在安装PyPI/pip之后和在本地运行它之后都能工作,我在正确地组织它时遇到了问题.

我主要有两个文件,例如my-package.pyutils.py我希望是可导入的,其中一个引用了另一个.我想要的文件组织是:

    LICENSE
    pyproject.toml
    README.md
    my-package/
        __init__.py
        my-package.py
        utils.py
    tests/

我希望能够pip install my-package,然后将此包导入新脚本中,如下所示: from my-package import my-function(或者,如果我不得不,from my-package.my-package import my-function),还有from my-package.utils import util-function

但是我也从我的-Package.py中的utils.py导入了一个util函数,到目前为止,我只能让它对pip或local起作用,但不能同时对两者都起作用.

这个可以用after pip installing,from my-package.my-package import my-function,也可以用from my-package.utils import util-function.但是,当我在本地try 运行python my-package.py时,我得到错误:ModuleNotFoundError: No module named 'my-package.utils'; 'my-package' is not a package.

我try 了一些from .my-packagefrom .utils版本的版本,但它们也有相对的导入错误.

我在这里可能要求太多了,但希望有一些相对轻松的指导可以遵循Re:组织+导入,这将使这种方法既适用于PIP后导入,也适用于本地运行脚本?

谢谢你所有的帮助!

推荐答案

不要将顶级程序包(即包含__init__.py文件的目录)命名为与其中包含的子模块名称完全相同的名称.这非常令人困惑,而且没有任何好处.

否则,这是一个很好的 struct :

LICENSE
pyproject.toml
README.md
my_package/
    __init__.py
    my_submodule.py
    utils.py
tests/

为了使在my_submodule.py中定义的函数可以从顶级名称空间导入,您需要在__init__.py中使用类似以下内容:

# my_package/__init__.py
from my_package.my_submodule import my_function

这将把my_function这个名字从my_package.my_submodule.__dict__"拉"到my_package.__dict__.

但是,当我在本地try 运行python my-package.py时,我得到错误:ModuleNotFoundError: No module named 'my-package.utils'; 'my-package' is not a package.

这是Relative imports for the billionth time美元.根本原因实际上与相对导入无关;使用绝对导入时也存在该问题.您的特定错误消息是不同的,因为在您的示例中,已导入的是子模块,而不是同名的顶级包(这可能意味着您在运行此命令时位于包目录中).这是将包和子模块命名为不同名称以避免导入混淆的原因之一.

在所有情况下,答案都是一样的:submodules are not scripts.不要试图将子模块作为脚本运行,再多的黑客攻击sys.path也不会让它正常工作.在PythonGuido considers that an anti-pattern中,不能很好地支持将包的子模块直接作为脚本运行.相反,标准解决方案是为包中定义的函数声明console_script entry points.PIP将在安装时自动生成入口点的包装器脚本.有关如何创建入口点的详细说明,请参阅我的答案here.

Python相关问答推荐

使用polars .滤镜进行切片速度比pandas .loc慢

将特定列信息移动到当前行下的新行

如何检测背景有噪的图像中的正方形

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

使用miniconda创建环境的问题

使可滚动框架在tkinter环境中看起来自然

OR—Tools CP SAT条件约束

numpy卷积与有效

如何创建一个缓冲区周围的一行与manim?

Pandas计数符合某些条件的特定列的数量

如何使用Pandas DataFrame按日期和项目汇总计数作为列标题

SQLAlchemy bindparam在mssql上失败(但在mysql上工作)

在代码执行后关闭ChromeDriver窗口

OpenGL仅渲染第二个三角形,第一个三角形不可见

为罕见情况下的回退None值键入

如何在Python中自动创建数字文件夹和正在进行的文件夹?

我怎样才能让深度测试在OpenGL中使用Python和PyGame呢?

具有不同坐标的tkinter canvs.cocords()和canvs.moveto()

某些值的数值幂和**之间的差异

如何在不不断遇到ChromeDriver版本错误的情况下使用Selify?