You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python自定义库toolbox嵌套导入问题:pip安装后导入失败

问题描述

我正在创建名为toolbox的Python自定义库,期望实现from toolbox.printing import warn的导入方式。当前项目架构如下:

repo
|--toolbox
|----__init__.py
|----printing
|------__init__.py
|------utils.py
|--demo.py
|--setup.py

toolbox/printing/utils.py代码为:

def warn(text: str):
    print(str)

本地运行demo.py(代码为from toolbox.printing import warn; warn("This is a warning"))时,通过在toolbox/__init__.py中写入from .printing import warn,toolbox/printing/__init__.py中写入from .utils import warn,可以正常执行。但在其他项目中通过pip install git+myRepo.git安装该库后,导入操作出现ModuleNotFoundError、循环导入等错误。我的setup.py代码如下:

import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setuptools.setup(
    name='toolbox',
    version='0.0.1',
    author='MyName',
    author_email='myEmail',
    description='Usefull functions for my personnal use',
    long_description=long_description,
    long_description_content_type="text/markdown",
    url='myRepo',
    project_urls = {
        "Bug Tracker": "myRepo"
    },
    license='MIT',
    packages=['toolbox'],
    install_requires=['requests',
                      'boto3',
                      'configparser'],
)

现请求解答:

  1. 应如何配置各个__init__.py文件以解决该问题?
  2. 该问题的本质是什么?是否是模块与库的差异导致的?
解决方案

1. 各文件的正确配置

首先修正setup.py

当前packages=['toolbox']只会打包toolbox根目录的文件,不会包含printing子模块,这是安装后找不到子模块的核心原因,改成自动发现所有子包:

import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setuptools.setup(
    name='toolbox',
    version='0.0.1',
    author='MyName',
    author_email='myEmail',
    description='Usefull functions for my personnal use',
    long_description=long_description,
    long_description_content_type="text/markdown",
    url='myRepo',
    project_urls = {
        "Bug Tracker": "myRepo"
    },
    license='MIT',
    # 替换原packages配置,自动发现所有子包
    packages=setuptools.find_packages(),
    install_requires=['requests',
                      'boto3',
                      'configparser'],
)

配置__init__.py文件

  • toolbox/__init__.py:如果不需要从toolbox根目录直接导出warn,可以留空;如果需要支持from toolbox import warn,则写入以下代码(不会导致循环导入):
    # 可选:需要从toolbox根目录导入warn时保留,否则留空
    from .printing import warn
    
  • toolbox/printing/__init__.py:从utils导入warn并向外导出,确保外部可以通过toolbox.printing.warn访问:
    from .utils import warn
    

修正utils.py的代码错误

原代码中print(str)会打印类型对象而非输入文本,改成:

def warn(text: str):
    print(text)

2. 问题本质分析

这个问题核心不是模块与库的差异,而是打包配置错误+本地与安装后运行环境的差异导致:

  • 本地运行时,Python会从当前项目根目录加载toolbox模块,此时printing子目录作为toolbox的子模块能被自动发现,所以即使setup.py配置错误,本地也能正常运行;
  • 当通过pip安装时,原setup.py的packages=['toolbox']只打包了toolbox根目录文件,没有包含printing子模块,导致安装后的库中不存在toolbox.printing,直接触发ModuleNotFoundError;
  • 所谓的“循环导入”大概率是后续错误修复时引入的,只要打包配置正确,原始的__init__.py导入逻辑不会产生循环导入问题。

内容的提问来源于stack exchange,提问作者Jechos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 23:03:21