Python 从上一级目录(包)导入模块
在Python中,从上一级目录导入模块的正确方法是什么?目录是一个包含所有这些模块的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
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('../..')