为什么一个__import__语句会影响下一个语句的有效性?

时间:2014-06-18 01:51:31

标签: python python-2.7 python-import

我正在查看包含两个__import__语句的代码,第二个__import__语句不起作用,除非第一个语句已经运行。

目录结构如下:

dir1
 |-__init__.py
 |-subdir1
 |  |-__init__.py
 |  |-file1.py
 |  |-file2.py
 |
 |-subdir2
    |-__init__.py
    |-file1.py
    |-file2.py

代码有两个__import__语句:

m = __import__('dir1.'+subdir1, fromlist=[file1])
...
m = __import__(file2, fromlist=[class_inside_file2])

第一个是有道理的 - 它大致相当于做

from dir1.subdir1 import file1

但允许动态提供子目录和文件。这是我不明白为什么会起作用的第二个陈述。它看起来应该相当于

from file2 import class_inside_file2

这不应该在file2.py subdir1中工作,但我当前的工作目录比其高两级。此外,所有__init__.py文件都是空的。

正如您所料,如果第二个import语句单独运行,则会失败并显示ImportError。但是,在第一个导入语句运行后第二个工作。为什么?

2 个答案:

答案 0 :(得分:5)

事实证明,解释相当愚蠢。 file1修改sys.path以将subdir1添加到路径中。如果路径上有subdir1,则显然可以直接找到file2而无需指定任何包。

故事的道德 - 副作用(比如导入模块时发生的事情)是愚蠢的,因为它经常会导致看似奇怪且难以诊断的问题。

答案 1 :(得分:4)

这不仅仅是__import__语句,因为我无法复制这种行为。

$ mkdir -p dir1/subdir1 dir1/subdir2
$ touch dir1/__init__.py dir1/subdir1/__init__.py dir1/subdir2/__init__.py
$ echo "print '1.1'" > dir1/subdir1/file1.py
$ echo "print '1.2'" > dir1/subdir1/file2.py
$ echo "print '2.2'" > dir1/subdir2/file2.py
$ echo "print '2.1'" > dir1/subdir2/file1.py

提供以下结构:

$ find . -name "*.py"
./dir1/__init__.py
./dir1/subdir1/__init__.py
./dir1/subdir1/file1.py
./dir1/subdir1/file2.py
./dir1/subdir2/__init__.py
./dir1/subdir2/file1.py
./dir1/subdir2/file2.py

然而,您发布的第二个__import__命令按预期失败:

$ python
Python 2.7.6 (default, Nov 18 2013, 11:23:24)
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.24)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> subdir1 = 'subdir1'
>>> file1 = 'file1'
>>> m = __import__('dir1.'+subdir1, fromlist=[file1])
1.1
>>> file2 = 'file2'
>>> class_inside_file2 = '*'
>>> m = __import__(file2, fromlist=[class_inside_file2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named file2