2017-04-16 59 views
2

这个问题是在python 2.7和相对导入的上下文中。我已经经历了相关的问题,但仍然不适合我。我不知道我在这里错过了什么?从兄弟目录导入的问题

以下是我的目录层次结构

. 
|-> wrapper.py 
|-> __init__.py 
|-> util 
| |-> hello.py 
| |-> __init__.py 
|-> src 
| |-> wrapper.py 
| |-> __init__.py 

所有__init__.py都是空白文件只能以“视该目录为一个包”

以下是./util/hello.py如何读取。这有它自己的主要功能,可以自行运行。

#!/usr/bin/python 
# This is hello.py. 

import sys 

# Define a main() function that prints a little greeting. 
def main(): 
    print "Hello World!!!" 

# Standard boilerplate that calls the main() function. 
if __name__ == '__main__': 
    main() 

以下是./wrapper.py的内容。这也有它自己的主要功能,并使用./util/hello.py来实现其目标。

#!/usr/bin/python 
# This is wrapper.py. 

import sys 
from util import hello 

# Define a main() function that prints a little greeting. 
def main(): 
    hello.main()  # This prints "Hello World!!!" 

# Standard boilerplate that calls the main() function. 
if __name__ == '__main__': 
    main() 

以下是./src/wrapper.py如何读取。

#!/usr/bin/python 
# This is wrapper.py. 

import sys 
from ..util import hello 

# Define a main() function that prints a little greeting. 
def main(): 
    hello.main()  # This prints "Hello World!!!" 

# Standard boilerplate that calls the main() function. 
if __name__ == '__main__': 
    main() 

正如你看到的,这是最小的变化./wrapper.py的几乎一模一样的副本,使其运行(进口变化)。所有__init__.py也存在。但是,任何尝试运行它都会导致以下错误。

Traceback (most recent call last): 
    File "wrapper.py", line 8, in <module> 
    from ..util import hello 
ValueError: Attempted relative import in non-package 

但是,如果我输入hello.py如下原理:

import os 
sys.path.append(os.path.abspath("../util/")) 
import hello 

两个问题:

Q1。我做错了什么或缺少我的注意力? Q2302。我怎样才能编码./src/__init__.py这样只需要“import hello”在./src/wrapper.py中工作?

+0

你是如何运行的'/ wrapper.py'?相关 - https://stackoverflow.com/questions/11536764/how-to-fix-attempted-relative-import-in-non-package-even-with-init-py –

+0

有很多现有的答案,解决Q1,简单搜索“尝试在非包装中进行相对导入”。我无法回答Q2,因为问题导致了错误的方向。你可以运行'python -m src.wrapper',然后同样''hello import hello''在'src/wrapper.py'中运行。我认为避免从一般顶级以外的地方进口相对明智的做法是明智的! – mhoff

+0

@AshishNitinPatil:以“python wrapper.py”的形式在“./src”中运行。 –

回答

1

简单的答案是,您需要为您的所有代码拥有一个父包。您不能仅将__init__.py放在根目录中,并期望它作为一个包进行操作。

我就会将你的选择为好和坏,从坏的:

坏 - 相对进口: 你应该做的是把包中的所有代码(又名.)命名适当(src是一个包顺便说一个坏名字)。说mypackage。然后,您将能够从Python路径中可用的位置导入src.wrapper,例如mypackage.src.wrapper,就像目录中打开的一个python解释器,其中包含mypackage。安装该软件包也可以在路径上使用。

有关相对进口的更多信息,以及为什么他们是坏的:

好 - 非相对进口: 更好的方法是导入通过以绝对的方式打包。您仍然必须创建一个父包mypackage,但是这次您将摆脱相对进口并使用中的import mypackage.util.hellowrapper.py之内。为此,您必须设置python路径以包含包含mypackage的目录。

推荐的方法是创建一个setup.py文件并安装您的软件包。为了发展,你应该使用python setup.py developpip install -e .

更多关于蟒蛇包装:https://packaging.python.org/distributing/

编辑: 您Q2,如果你使用绝对导入,您可以使用import mypackage.util.hello as hellofrom mypackage.util import hello。两者都是一样的。

在某些特殊情况下,你可能有兴趣在写import util.hello as hello/mypackage/__init__.py,然后你可以使用from mypackage import hello