形式的import语句绑定模块名称

形式的import语句绑定模块名称

本文介绍了为什么Python的`from`形式的import语句绑定模块名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下结构的Python项目:

I have a Python project with the following structure:

testapp/
├── __init__.py
├── api
│   ├── __init__.py
│   └── utils.py
└── utils.py

所有模块都是空的,除了 testapp / api / __ init __。py ,其中包含以下代码:

All of the modules are empty except testapp/api/__init__.py which has the following code:

from testapp import utils

print "a", utils

from testapp.api.utils import x

print "b", utils

testapp / api / utils.py 定义 x

x = 1

现在来自root我导入 testapp.api

Now from the root I import testapp.api:

$ export PYTHONPATH=$PYTHONPATH:.
$ python -c "import testapp.api"
a <module 'testapp.utils' from 'testapp/utils.pyc'>
b <module 'testapp.api.utils' from 'testapp/api/utils.pyc'>

导入的结果令我感到惊讶,因为它显示第二个导入语句已覆盖 utils 。然而,文档声明:

The result of the import surprises me, because it shows that the second import statement has overwritten utils. Yet the docs state that the from statement will not bind a module name:

事实上,当我在终端中使用来自... import ... 语句的时,不会引入任何模块名称:

And indeed, when in a terminal I use a from ... import ... statement, no module names are introduced:

>>> from os.path import abspath
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined

我怀疑这与Python有关,在第二个import语句时,尝试导入 testapp.api.utils ,它引用 testapp.utils 并且失败但我不确定。

I suspect this has to do with Python, at the time of the second import statement, trying to import testapp.api.utils which refers to testapp.utils and failing but I'm not certain.

这里发生了什么?

推荐答案

来自:

spam/
    __init__.py
    foo.py
    bar.py

spam / __ init__。 py 中包含以下几行:

from .foo import Foo
from .bar import Bar

然后执行以下命令将名称绑定到 foo bar
垃圾邮件模块:

then executing the following puts a name binding to foo and bar in the spam module:

>>> import spam
>>> spam.foo
<module 'spam.foo' from '/tmp/imports/spam/foo.py'>
>>> spam.bar
<module 'spam.bar' from '/tmp/imports/spam/bar.py'>

鉴于Python熟悉的名称绑定规则,这可能看起来令人惊讶,
但它实际上是一个基本功能进口系统
不变量持有是如果你有 sys.modules ['spam']
sys.modules ['spam .foo'] (就像上面的导入一样),
后者必须显示为前者的 foo 属性。

Given Python’s familiar name binding rules this might seem surprising, but it’s actually a fundamental feature of the import system. The invariant holding is that if you have sys.modules['spam'] and sys.modules['spam.foo'] (as you would after the above import), the latter must appear as the foo attribute of the former.

如果从testapp.api.utils导入x 执行,则导入语句不会将 utils 加载到本地名称空间中。但是,导入机器加载 utils testapp.api 命名空间中进一步的进口工作。恰好在你的情况下, testapp.api 也是本地命名空间,所以你会感到意外。

If you do from testapp.api.utils import x, the import statement will not load utils into the local namespace. However, the import machinery will load utils into the testapp.api namespace, to make further imports work right. It just happens that in your case, testapp.api is also the local namespace, so you're getting a surprise.

这篇关于为什么Python的`from`形式的import语句绑定模块名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 16:15