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

Python目录转包后导入RecipeManager类失败,求失效原因

问题说明

我知道这个问题已有相关提问,试过现有解决方案但没效果。我想把目录转为Python包,将recipeProject.py里的RecipeManager类导入到testExportRecipes.py中,同时保持清晰的目录结构(测试文件单独放在专属文件夹)。用文件开头注释的sys.path方案能正常运行,但我更倾向于包化导入的方式,想搞清楚当前方案失效的原因。最后我试过按照Stack Overflow的方法从项目父目录运行文件,问题还是没解决。

当前代码片段

testExportRecipes.py

# import os, sys
# CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
# sys.path.append(os.path.dirname(CURRENT_DIR))

import unittest

from NewProjectJustDropped.recipePackage.recipeProject import RecipeManager


class TestRecipeManagement(unittest.TestCase):

    def test_exported_JSON_file(self):
        rm = RecipeManager()

recipeProject.py(片段)

import json
import os

class RecipeManager:
    def __init__(self):
        self.data = [
            {
                "id": 0,
                "recipeName": "McBurger",
                "recipeAuthor": "Sam",
                "prepTime": 10,
                "cookTime": 12,
                "servingSize": 1,
                "ingredients": [
                    {"ingredientName": "bun", "quantity": 1, "measurement": "unit"},
                    {"ingredientName": "secretPatty",
                     "quantity": 1, "measurement": "unit"},
                    {"ingredientName": "specialMayo",
                     "quantity": 10, "measurement": "grams"},
                    {"ingredientName": "specialSauce",
                     "quantity": 20, "measurement": "grams"},
                    {"ingredientName": "lettuce",
                     "quantity": 8, "measurement": "grams"},
                    {"ingredientName": "tomato",
                     "quantity": 8, "measurement": "grams"}
                ],
                "instructions": {
                    "1": "Assemble the bun and the secret patty.",
                    "2": "Spread special mayo and special sauce on the bun.",
                    "3": "Add lettuce and tomato on top.",
                    "4": "Cook the assembled burger for 12 minutes."
                }
            }
        ]

    def viewRecipe(self):  
        # this method should print all recipes to the screen.
        pass
失效原因分析
  • 缺少__init__.py文件:Python要把目录识别为合法包,必须在每个包级目录下放置空的__init__.py文件。如果你的NewProjectJustDropped、recipePackage目录下没有这个文件,Python不会把它们当作可导入的包。
  • 导入路径与实际目录结构不匹配:如果你的testExportRecipes.py是放在NewProjectJustDropped内部的tests文件夹里,那用from NewProjectJustDropped.recipePackage...这种绝对路径就会出错——因为此时测试文件已经在NewProjectJustDropped包内部,应该用相对路径或者直接从recipePackage开始导入。
  • Python路径未包含项目根目录:即使你从父目录运行文件,如果项目根目录没被加入Python的sys.path列表,Python依然找不到NewProjectJustDropped这个顶级包。
包化导入的正确步骤

假设你想要的规范目录结构是这样:

你的项目根目录/
├─ NewProjectJustDropped/
│  ├─ __init__.py
│  ├─ recipePackage/
│  │  ├─ __init__.py
│  │  └─ recipeProject.py
│  └─ tests/
│     ├─ __init__.py
│     └─ testExportRecipes.py
  1. 添加__init__.py文件
    在NewProjectJustDropped、recipePackage、tests这三个目录下各创建一个空的__init__.py文件,让Python把它们识别为包。

  2. 调整导入语句
    因为testExportRecipes.py在NewProjectJustDropped/tests目录下,属于NewProjectJustDropped包的子目录,所以导入语句应该改成:

    from recipePackage.recipeProject import RecipeManager
    
  3. 正确运行测试
    从项目根目录(也就是包含NewProjectJustDropped的那个文件夹)运行测试命令:

    # 使用unittest运行
    python -m unittest NewProjectJustDropped.tests.testExportRecipes
    # 或者如果用pytest
    python -m pytest NewProjectJustDropped/tests/testExportRecipes.py -v
    

    这种方式会自动把项目根目录加入Python路径,确保包能被正确找到。

  4. 可选:更规范的项目配置
    如果你想让包在任何环境下都能被导入,可以在项目根目录创建pyproject.toml文件,内容如下:

    [build-system]
    requires = ["setuptools>=61.0"]
    build-backend = "setuptools.build_meta"
    
    [project]
    name = "NewProjectJustDropped"
    version = "0.1.0"
    packages = ["NewProjectJustDropped"]
    

    然后在项目根目录运行pip install -e .,把包以可编辑模式安装,之后不管在哪个位置都能直接导入recipePackage里的模块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:13:17