简体   繁体   English

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

[英]Why does one __import__ statement affect the validity of the next one?

I was looking at some code with two __import__ statements, and the second __import__ statement doesn't work unless the first one has already been run. 我正在查看带有两个__import__语句的代码,第二个__import__语句不起作用,除非第一个已经运行。

The directory structure is like this: 目录结构如下:

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

The code has two __import__ statements: 代码有两个__import__语句:

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

The first one makes sense - it is roughly the equivalent of doing 第一个是有道理的 - 它大致相当于做

from dir1.subdir1 import file1

but allows for the subdirectory and file to be provided dynamically. 但允许动态提供子目录和文件。 It is the second statement that I don't understand why it works. 这是第二个声明,我不明白它为何起作用。 It looks like it should be the equivalent of 它看起来应该相当于

from file2 import class_inside_file2

This shouldn't work as file2.py is in subdir1 , but my current working directory is two levels above that. 这不应该工作,因为file2.pysubdir1 ,但我当前的工作目录比它高两级。 Additionally, all of the __init__.py files are empty. 此外,所有__init__.py文件都是空的。

As you would expect, the second import statement fails with an ImportError if it is run by itself. 正如您所料,如果第二个import语句由其自身运行,则会失败并显示ImportError However, after the first import statement has run the second one works. 但是, 在第一个import语句运行后,第二个工作正常。 Why? 为什么?

It turns out the explanation is rather dumb. 事实证明,解释相当愚蠢。 file1 modifies sys.path to add subdir1 to the path. file1修改sys.path以将subdir1添加到路径。 With subdir1 on the path, it can obviously find file2 directly without having specify any packages. 使用路径上的subdir1 ,它显然可以直接找到file2而无需指定任何包。

Moral of the story - side effects (like things happening when you import a module) are dumb because it can frequently cause issues that seem bizarre and can be hard to diagnose. 故事的道德 - 副作用(比如导入模块时发生的事情)是愚蠢的,因为它经常会导致看似奇怪且难以诊断的问题。

It is not just the __import__ statements as I can't replicate this behavior. 它不仅仅是__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

Gives the following structure: 给出以下结构:

$ 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

However the 2nd __import__ command you've posted fails as expected: 但是,您发布的第二个__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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM