sách gpt4 ai đã đi

python - 在循环引用下理解python的import *机制

In lại 作者:行者123 更新时间:2023-11-28 22:45:28 33 4
mua khóa gpt4 Nike

我为了回答aquestion posted here on SO而玩示例,发现很难理解python的nhập khẩu *破坏作用域的机制。
首先是一点上下文:这个问题不涉及实际问题;我很清楚from foo import *是不受欢迎的(这是正确的),而且我明白,这是因为代码中的原因比清晰性更深。我在这里的兴趣是理解导致循环不良行为的机制。换句话说,我理解观察到的行为是预期的;我不明白为什么。
我无法理解的情况是,当使用导入模块(nhập khẩu *)引用导入模块(b)时出现的问题。当导入模块使用Một或不使用*时,我设法观察到行为上的细微差异,但总体(不良)行为是相同的。我找不到任何明确的解释,无论是在文件中还是在这样。
通过对作用域上可用内容的调查,我构建了一个小示例,根据上述问题和我在SO和其他地方进行的一些搜索,说明了其内容的差异。我尽量简洁地演示。下面的所有代码和实验都是用Python2.7.8完成的。
工作场景
首先是包含包含一个类的平凡模块的平凡模块,*:

class A:
vượt qua

客户端代码的第一个变体,导入模块A, a.py:
from pprint import pprint

def dump_frame(offset=0):
nhập khẩu hệ thống
frame = sys._getframe(1+offset)
d = frame.f_globals
d.update(frame.f_locals)
return d

print 'before import v1'
pprint (dump_frame())

import a

print 'after import v1'
pprint (dump_frame())
print a.A()

同一代码的第二个变体,从模块导入 b_v1.py, *:
from pprint import pprint

def dump_frame(offset=0):
nhập khẩu hệ thống
frame = sys._getframe(1+offset)
d = frame.f_globals
d.update(frame.f_locals)
return d

print 'before import v2'
pprint (dump_frame())

from a import *

print 'after import v2'
pprint (dump_frame())
print A()

在导入之前同时运行 Mộtb_v2.py会产生相同的输出,并且两者都能够按预期实例化。然而,正如预期的那样,在进口之后,它们又有所不同。我强调了区别:
b_v1,在范围内
'a': 

b_v2没有,但是
'A': 

导入前后,作用域都包含设置为 b_v1.pycủa b_v2.py.
两个变量都成功地实例化了 __builtins__.
不工作的情况
有趣的行为是当改变 以包含对 MỘT的循环引用时(在 a.pyb变体中)。
调整代码:
from b_v1 import *
class A:
vượt qua

(简而言之,只显示了一个 b_v1的情况;显然,在 b_v2的情况下,导入是针对这个模块的,而不是针对 a.py)
在我用循环引用对场景中范围内容的观察中,我看到:
在这两种变体中,在导入 a.py之前, b_v2.py与上述情况相似。但是,在导入之后,它被更改并包含
“算术错误”:,
'断言错误':,
'属性错误':,
...
在这里粘贴的时间是不必要的。
更改的 b_v1.py出现两次。我可以理解这是导入的结果,如果代码在函数中,则可能不会发生这种情况。
在variant Một中,模块 __builtins__出现在范围中;它出现在variant dictở giữa.
在这两种变体中, __builtins__的实例化都失败。考虑到在variant b_v2中,该模块存在于作用域中(因此,我假设已成功导入),我本来希望能够实例化 Một。事实并非如此。但也有区别:在 b_v1情况下,它以 MỘT失败,而对于 b_v1,失败是a MỘT。在后一种情况下,无论我是否尝试实例化为 b_v1.py(如工作示例中所示)的 AttributeError: 'module' object has no attribute 'A',它总是相同的错误。
总结我的问题:
一个圆形的物体通过什么机械装置把望远镜弄乱了?
为什么在b v1的情况下不能实例化 b_v2.py,尽管模块在作用域中?

1 Câu trả lời

Python模块自上而下执行。导入语句和其他语句一样是可执行的。当import语句运行时,它会执行以下操作(为了便于说明,请参阅language reference以了解详细信息):
检查模块是否在sys.modules中列出。如果是,请立即归还
查找模块(通常但不总是通过搜索文件系统)。
hiện hữusys.modules中为模块创建一个空条目,名称空间为空。
在新创建的命名空间中自上而下执行模块。
假设我们有这样的文件:
a.py:

from b import *
foo = object()

b.py:
from a import *
print(repr(foo))

进一步假设 a.py首先被导入。让我们一行一行地看一下:
其他人导入 Một。在我们开始执行之前,对 Một的引用存储在 sys.modules['a']ở giữa.
a.pychạy from b import *。这将转换为“ import b,然后将 b命名空间中的所有内容获取到 Một命名空间中。”
Python在 sys.modules['b']
b.pychạy from a import *。Python导入 Một.
Một以来,立即导入 sys.modules['a']返回。
由于 a.py尚未执行 foo = object(), a.foo尚未存在,因此不能倾倒到 b命名空间中。
b.py在上崩溃。

关于python - 在循环引用下理解python的import *机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28551513/

33 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com