gpt4 book ai didi

python循环导入和异常类的定义

转载 作者:太空宇宙 更新时间:2023-11-03 11:50:11 25 4
gpt4 key购买 nike

我知道 python 通过在 sys.modules 中创建引用来处理循环导入的方式。但是请看这两个模块和定义异常类的问题:

a.py

import b
class Err(Exception):
pass
if __name__ == '__main__':
try:
b.f()
except Err:
pass

b.py

from a import Err
def f():
raise Err()

似乎我们应该捕获错误,但它不正确。运行 a.py 的输出是:

$ python a.py
Traceback (most recent call last):
File "a.py", line 8, in <module>
b.f()
File "b.py", line 4, in f
raise Err()
a.Err

好的,现在让我们在代码中添加一些日志以使其更加清晰:

a.py:

print 'A1'
import b
print 'A2'

class Err(Exception):
pass

print 'A3', 'id(Err)=%x' % id(Err)

if __name__ == '__main__':
try:
b.f()
except Err:
pass

b.py

print 'B1'
from a import Err

print 'B2', 'id(Err)=%x' % id(Err)

def f():
raise Err()

输出是:

$ py a.py
A1
B1
A1
A2
A3 id(Err)=23fa750
B2 id(Err)=23fa750
A2
A3 id(Err)=23f9740
Traceback (most recent call last):
File "a.py", line 12, in <module>
b.f()
File "b.py", line 7, in f
raise Err()
a.Err

如您所见,python 定义了 Err 两次,Err0x23fa7500x23f9740< 处有两个不同的类对象。如果您使用 isinstance 函数和 a.Err 类测试 b.Err 的实例,您将得到 False。所以捕获异常的唯一方法是使用 b.Err 而不是 Err。但这不是我们乍一看所期望的,也不是我们想要的。

我知道的解决方案是创建一个新模块c.py 并在其中定义Err 类。然后 a.pyb.py 都应该从 c.py 导入 Err。它解决了这个问题。

但是有没有一种解决方案可以让我们在a.py中定义Err?请注意,问题不仅仅与异常类有关,任何 python 类都可能根据我们在代码中使用其对象的方式而陷入此坑。

最佳答案

当您在模块末尾添加 if __name__ == '__main__': 然后引用前面代码中定义的内容时,这与导入不同并使用该模块(一方面,__main__ 模块未缓存在 sys.modules 中)。您可以通过以下修改使您的第一个示例正常工作:

a.py

import b
class Err(Exception):
pass
if __name__ == '__main__':
from a import Err # add this
try:
b.f()
except Err:
pass

输出:

... nothing, which is correct

关于python循环导入和异常类的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29874988/

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