从目录(包)向上一级导出模块

时间:2015-09-24 17:21:53

标签: python

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

以下工作正常,但这只是一个黑客。我想要推荐/ pythonic方式。

import sys
sys.path.append("../")
from fruit import Fruit
print("OK")

目录结构:

pkg1
   __init__.py  
   fruit.py  
   +sub_pkg
      __init__.py
      recipe.py

fruit.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

我也试过:from pkg1.fruit import Fruit,不起作用。还看了其他类似的问题.. python -m recipe.pypython -m sub_pkg/recipe.py无效。

4 个答案:

答案 0 :(得分:3)

在您的主文件recipe.py中添加pkg1的{​​{1}}路径

PYTHONPATH

或使用相对路径

sys.path.append('/path/to/pkg1')

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

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

关于Python 2.5中PEP328的相对导入:

  

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


Guido建议在相对导入中使用前导点以避免上述含义不明确的导入,再次从PEP328开始:

  

Guido已发表相关进口将使用领先点。单个前导点表示相对导入,从当前包开始。两个或多个前导点为当前包的父级提供相对导入,在第一个包之后每个点一个级别。

答案 1 :(得分:2)

如果您遇到问题,也可以使用以下内容。

从当前目录

导入
from . import something

从上面的一个目录导入

from .. import fruit

相对路径的文档:https://docs.python.org/2/tutorial/modules.html#intra-package-references

RELATIVE PACKAGE ISSUE ValueError:在非包裹中尝试相对导入

对于遇到相关包裹问题的人。这是您的解决方案。

if __name__ == "__main__" and __package__ is None:
    __package__ = "expected.package.name"

另外说明是从另一个python docs

复制而来的
  

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

if __name__ == "__main__" and __package__ is None:
    __package__ = "expected.package.name
  

请注意,只有顶层包可以通过sys.path访问时,此样板才足够。需要操作sys.path的其他代码才能使直接执行工作,而顶层包不能被导入。

创建包的文档 我不打算粘贴内容,因为它相当长,但这里是python文档中用于创建包的部分。 https://docs.python.org/2/tutorial/modules.html#packages

关于PYTHONPATH的更多文档 https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH

答案 2 :(得分:0)

您可以使用relative imports

from ..fruit import Fruit

答案 3 :(得分:-1)

不是使用上层导入,而是有一个可以从最高级别调用的入口点,并且相对于recipe.py文件中的入口点具有导入。

例如:

pkg1/
   __init__.py  
   main.py
   fruit.py  
   +sub_pkg
      __init__.py
      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

要运行,请致电python3 main.py