Python 从上一级目录(包)导入模块

Python 从上一级目录(包)导入模块,python,Python,在Python中,从上一级目录导入模块的正确方法是什么?目录是一个包含所有这些模块的Python包,我有一个子目录,其中包含需要这些模块的代码 下面的工作很好,但这只是一个黑客。我想要推荐的/蟒蛇式的方法 import sys sys.path.append("../") from fruit import Fruit print("OK") 目录结构: pkg1 __init__.py fruit.py +sub_pkg __init__.py

在Python中,从上一级目录导入模块的正确方法是什么?目录是一个包含所有这些模块的Python包,我有一个子目录,其中包含需要这些模块的代码

下面的工作很好,但这只是一个黑客。我想要推荐的/蟒蛇式的方法

import sys
sys.path.append("../")
from fruit import Fruit
print("OK")
目录结构:

pkg1
   __init__.py  
   fruit.py  
   +sub_pkg
      __init__.py
      recipe.py
果皮含量

class Fruit:
   def get_name(self):
       print("Fruit name")
sub_-pkg/recipe.py的内容。。只有一个导入行:

from fruit import Fruit
当我跑步时:

python recipe.py
它给出了以下错误

Traceback (most recent call last):
  File "recipe.py", line 2, in <module>
    from fruit import Fruit
ImportError: No module named fruit
回溯(最近一次呼叫最后一次):
文件“recipe.py”,第2行,在
从水果进口水果
导入错误:没有名为FROUT的模块
我还尝试过:
从pkg1.fruit导入水果
,不起作用。还研究了其他类似的问题。。
python-m recipe.py
python-m sub_pkg/recipe.py
不起作用

如果您遇到问题,也可以使用以下方法

这将从当前目录导入

from . import something
此导入来自上面的一个目录

from .. import fruit
相对路径的文档:

相对包问题值错误:尝试在非包中进行相对导入

适用于对相关软件包有问题的人。这是你的解决方案

if __name__ == "__main__" and __package__ is None:
    __package__ = "expected.package.name"
还有从另一个复制的解释

当主模块由其文件名指定时,属性将设置为无。为了在直接执行模块时允许相对导入,在第一个相对导入语句之前需要类似于以下内容的样板文件:

注意,只有当顶层包已经可以通过sys.path访问时,此样板文件才足够。需要额外的代码来操作sys.path,以便在顶层包不可导入的情况下直接执行

用于创建包的文档 我不打算粘贴内容,因为它相当长,但这里是关于python文档创建包的部分。

PYTHONPATH上还有一个文档 您可以使用:


不要使用上层导入,而是使用一个可以从最上层调用的入口点,并在
recipe.py
文件中相对于该入口点进行导入

例:

其中
main.py
包含:

#!/usr/bin/env python3

import subpkg.recipe as recipe
import fruit

if __package__ is None and __name__ == "__main__":
    __package__ = "main"
    print()
    # Call recipe.py or fruit.py methods from here
recipe.py
中:

import fruit
# do stuff with fruit module, which is properly imported now

要运行,请在主文件
recipe.py
中调用
python3 main.py

,将
pkg1
路径添加到
PYTHONPATH

sys.path.append('/path/to/pkg1')
或者使用相对路径

sys.path.append('../..')
这应该允许从程序中的任何位置导入
pkg1


正如这里所建议的,总是可以选择使用相对导入,我发现使用绝对导入更具可读性,也不太可能导致bug。此外,在使用相对导入的大型项目中,您将不断计算路径层次结构,而在使用绝对导入时,很容易知道您始终引用一个根目录

关于Python 2.5中的相对导入:

阅读依赖于相对导入的代码也不太清晰,因为读者可能会对要使用的模块感到困惑。Python用户很快就学会了不要在包的子模块名称中重复标准库模块的名称,但是您无法防止子模块的名称被用于Python未来版本中添加的新模块


建议在相对导入中使用前导点,以避免如上所述的不明确导入,再次:

Guido宣布相对导入将使用前导点。单个前导点表示相对导入,从当前包开始。两个或多个前导点向当前包的父级提供相对导入,第一个点后每个点一个级别


关于这个答案:从pkg1.fruit导入fruit
得到的
错误是什么?@Irit:
导入错误:没有名为temp.fruit
的模块,您应该将
pkg1
添加到PYTHONPATH。如果您在正确的位置安装python包,您不需要从上面的目录导入。上层导入通常不是一个好主意,它显示了糟糕的程序设计。设置系统路径,然后像往常一样导入是一个比下面提到的相对导入更好的解决方案,后者在python3上几乎同时中断!!谢谢如果我执行这些操作,将导致
ValueError:尝试在非包中进行相对导入
。这与Olexander在另一个问题中指出的错误相同。但我不明白解决办法!你引用了文档。这总是更有益的。在python3中不起作用
SystemError:未加载父模块“”,无法执行相对导入
small correction只有当您在正确的python包中且上面的目录是正确的python包时,“此从上面的一个目录导入”才为真。(即,所有东西都有一个init.py,并被设计为python包)。如果您只是想在通用文件系统上升级一级,那么您需要更改python搜索的路径。只在脚本中寻址包会更有益。而不是创建单独的运行脚本。这消除了脚本在其上运行的可能性,在某些情况下可能无法扩展。@AdriVelaz在哪个列表中寻址哪个包?我需要一些上下文
\uuuuuu package\uuu=“expected.package.name”
使用脚本级别的
if\uuuuuuuuu name\uuu==“\ uuuuuuu main\uuuuu”:
这里还有文档。完成,但除了python的正确性之外,它并没有在脚本级别添加任何内容来解决OP的问题—它定义了包的上下文。它回答了OP的问题。这是在任何正式导入之前完成的。根据文档,设置PYTHONPATH是可行的,似乎是一个可接受的解决方案(将pkg添加到搜索路径)。
import fruit
# do stuff with fruit module, which is properly imported now
sys.path.append('/path/to/pkg1')
sys.path.append('../..')