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

Python 为什么一个import语句会影响下一个语句的有效性?,python,python-2.7,python-import,Python,Python 2.7,Python Import,我在看一些带有两个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu语句的代码,第二个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 目录结构如下所示: dir1 |-__init__.py |-subdir1 | |-__init__.py | |-file1.py | |-file2.py | |-subdir2 |-__init__.py |-file1.py |-fi

我在看一些带有两个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
语句的代码,第二个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

目录结构如下所示:

dir1
 |-__init__.py
 |-subdir1
 |  |-__init__.py
 |  |-file1.py
 |  |-file2.py
 |
 |-subdir2
    |-__init__.py
    |-file1.py
    |-file2.py
该代码有两个
\uuuuuuuuuuuuuuuuuuuuuu
语句:

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
子目录1
中,但我当前的工作目录比它高两级。此外,所有
\uuuu init\uuuu.py
文件都是空的


正如您所期望的,如果第二条import语句是自己运行的,那么它将失败,并出现一个
ImportError
。但是,在第一个import语句运行后,第二个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
但是,您发布的第二个_u导入_;命令按预期失败:

$ 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
$python
Python 2.7.6(默认值,2013年11月18日,11:23:24)
[GCC 4.2.1达尔文兼容苹果LLVM 4.2(clang-425.0.24)]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>subdir='subdir1'
>>>file1='file1'
>>>m=\uuuuu导入(dir1.+subdir1,fromlist=[file1])
1.1
>>>file2='file2'
>>>类\u在\u文件2中='*'
>>>m=\uuuuu导入(文件2,fromlist=[class\u在文件2中])
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ImportError:没有名为file2的模块

原来这个解释相当愚蠢
file1
修改
sys.path
以将
subdir1
添加到路径中。使用路径上的
subdir1
,它显然可以直接找到
file2
,而无需指定任何包


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

具有导入功能的代码在哪里?另外,第二个文件是否有
file2
“file2”
?从你的帖子中不清楚哪些东西是变量,哪些是文字字符串。@Brenburn大多数都是变量,当代码被计算时,这些变量将保存这些文字值,即
file2
将具有值
“file2”
。file1是否修改了
sys.modules
,但它确实修改了
sys.path
。谢谢你让我找那个!请注意,
help(\uuuuu import\uuuuuu)
声明“因为此函数是供Python解释器使用的,而不是一般用途,所以最好使用importlib.import\u module()以编程方式导入模块。”这不是答案。对这个问题发表评论,只说你的第一句话,会更好。@BrenBarn我考虑过这一点,但这也允许其他人尝试(例如在不同的平台上),并在出现错误时纠正我的过程。为什么你觉得信息越少越好?@PeterGibson:最好依靠提问者发布(在问题中)他在做什么,然后让其他人试试。这并不能提供问题的答案。若要评论或要求作者澄清,请在其帖子下方留下评论。@PeterGibson认为该问题是第一次导入的副作用,我认为这实际上是一个非常相关的答案。