在作为__main__程序执行时导入兄弟目录中的模块

时间:2015-06-24 06:44:00

标签: python python-2.7

在Python 2.7上,我有以下内容:

$ tree dir1
dir1
├── __init__.py
├── __init__.pyc
├── dir2
│   ├── File1.py
│   ├── File1.pyc
│   ├── __init__.py
│   └── __init__.pyc
└── dir3
    ├── File2.py
    ├── File2.pyc
    ├── __init__.py
    └── __init__.pyc

2 directories, 10 files



$ cat dir1/dir2/File1.py
print  __name__ + " imported successfully"
def fun():
    print "fun"

$ cat dir1/dir3/File2.py #case1
if __name__ != '__main__':
    from dir1.dir2 import File1
    print "worked"
else:
    from ..dir2 import File1

$ cat dir1/dir3/File2.py #case2
if __name__ != '__main__':
    from dir1.dir2 import File1
    print "worked"
else:
    from dir1.dir2 import File1

$ pwd
/Users/abc
$ python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dir1.dir3.File2
dir1.dir2.File1 imported successfully
worked

但是当我这样做时:

$ python dir1/dir3/File2.py #case1
Traceback (most recent call last):
  File "dir1/dir3/File2.py", line 5, in <module>
    from ..dir2 import File1
ValueError: Attempted relative import in non-package

$ python dir1/dir3/File2.py #case2
Traceback (most recent call last):
  File "dir1/dir3/File2.py", line 5, in <module>
    from dir1.dir2 import File1
ImportError: No module named dir1.dir2

为什么这个错误以及非hacky,pythonic,标准的做法是什么?

2 个答案:

答案 0 :(得分:0)

由于你有 init .py,整个事情就变成了dir1级别的模块。

所以你可以使用相对导入:

from ..dir2 import File1

但是,这可以通过在dir1级别的包级别导入它来实现。如果您不打算将软件包用作软件包,则需要“hacky”。而且,hacky,我们只是想告诉它在哪里实际导入目录。只需将其添加到sys.path,您就可以稍后弹出它(如果您担心路径由于某种原因变得过于拥挤)。否则,没有什么可以指导导入:它不能依赖于“非包”中的包接口,因为您没有将包用作一个包。

导入模块,然后按如下方式导入file2。

如果没有 init .py或者你不想在包级别执行它,那么一种方法就是将dir1目录添加到路径然后导入文件和里面的名字。

示例:

import os
import sys

FILE = os.path.realpath(__file__)
HOME = os.path.dirname(FILE)
sys.path.append(HOME)

from dir2 import File1

您也可以使用相对路径,只需执行:

import sys

sys.path.append('..')

from dir2 import File1

答案 1 :(得分:0)

阅读教程中的Intra Package References。它说

  

请注意,显式和隐式相对导入均基于   当前模块的名称。由于主模块的名称是   总是&#34; 主要&#34;,模块用作a的主要模块   Python应用程序应始终使用绝对导入。

所以相对进口不起作用。你需要确保你的包dir1在PYTHONPATH中然后你这样做:

from dir1.dir2 import File1