gpt4 book ai didi

python - 为什么 Python 2 在使用 "import ... as ..."时会尝试获取模块作为包属性?

转载 作者:行者123 更新时间:2023-12-04 09:39:31 25 4
gpt4 key购买 nike

EDIT: closely related to Imports in __init__.py and import as statement. That question deals with the behaviour of import ... as ... for up to Pyhon 3.6. The change in behaviour I'm describing below was introduced in Python 3.7, with the intention to fix the bug described in that other question. I'm more interested in where the change is documented (or where the two different behaviours, for Py2 up to Py3.6 vs Py3.7+, are respectively documented) rather than how exactly this behaviour arises (as I already mostly understand that as a result of experimenting in preparation for this question).



考虑以下目录结构:

.
└── package
├── __init__.py
├── a.py
└── b.py
__init__.py文件为空。两个模块 package.apackage.b分别包含:

# package.a
import sys

print('package.b' in sys.modules)
import package.b as b

spam = 'ham'
print("{} says b is {}".format(__name__, b))

# package.b
import package.a

print("{} says package.a.spam is {}".format(__name__, repr(package.a.spam)))

Python 3.x (特别是 3.8),当我运行 python -c "from __future__ import print_function; import package.b"从根目录,我得到

True
package.a says b is <module 'package.b' from 'C:\\[...]\\package\\b.py'>
package.b says package.a.spam is 'ham'

但与 Python 2.x (特别是 2.7)我得到

True
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "package\b.py", line 1, in <module>
import package.a
File "package\a.py", line 4, in <module>
import package.b as b
AttributeError: 'module' object has no attribute 'b'

问题是:是什么保证了这种差异?此更改记录在哪里,例如Python 文档、PEP 或类似文档?



我明白了 package.b package.a 时尚未完成初始化已导入,因此 package.b 的模块对象尚未添加为 package 的模块对象的属性.但是模块对象本身仍然存在(因为它被添加到 sys.modules ),所以绑定(bind)名称应该没有任何问题 b到那个对象,我相信 Python 3 是什么? Python 2 似乎没有将其直接绑定(bind)到模块对象,而是尝试通过获取名为 'b' 的属性来获取它。来自 package 的模块对象.

据我所知,文档中没有这样的规范。

Import statement (Python 3.8) :

If the requested module is retrieved successfully, it will be made available in the local namespace in one of three ways:

  • If the module name is followed by as, then the name following as is bound directly to the imported module.

[...]



Import statement (Python 2.7) :

The first form of import statement binds the module name in the local namespace to the module object, and then goes on to import the next identifier, if any. If the module name is followed by as, the name following as is used as the local name for the module.





笔记:
  • 使用 from package import bpackage/a.py产生相同的结果,只是有不同的错误(即 ImportError 而不是 AttributeError )。我怀疑 ImportError只是包装底层 AttributeError .
  • 使用 import package.bpackage/a.py不给 AttributeError在 Py2 中导入时。但是,当然,引用 package.b稍后在打印调用中产生 AttributeError在 Py2 和 Py3 中。
  • 最佳答案

    如果你这样做

    import package.submodule

    然后尝试访问 package.submodule ,该访问是对模块对象的属性查找 package ,它会找到绑定(bind)到 submodule 的任何对象。属性(如果该属性未设置,则失败)。为了一致性,
    import package.submodule as whatever

    执行相同的属性查找以查找要绑定(bind)到 whatever 的对象.

    这是 changed在 Python 3.7 中回退到 sys.modules['package.submodule']如果属性查找失败,则查找。进行此更改是为了与 previous change 保持一致。在 Python 3.5 中制作 from package import submodule回退到 sys.modules查找,并且进行了更改以使相对导入更加方便。

    关于python - 为什么 Python 2 在使用 "import ... as ..."时会尝试获取模块作为包属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62394688/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com