加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python循环导入和定义异常类

发布时间:2020-12-20 13:49:04 所属栏目:Python 来源:网络整理
导读:我知道 python通过在sys.modules中创建引用来处理循环导入的方式.但请看这两个模块以及定义异常类的问题: a.py import bclass Err(Exception): passif __name__ == '__main__': try: b.f() except Err: pass b.py from a import Errdef f(): raise Err() 似
我知道 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()

似乎我们应该抓住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,line 7,in f
    raise Err()
a.Err

正如您所看到的,python定义了Err两次,并且Err在0x23fa750和0x23f9740处有两个不同的类对象.如果使用isinstance函数和a.Err类测试b.Err的实例,则会得到False.因此,捕获异常的唯一方法是使用b.Err而不是Err.但这不是我们一见钟情,也不是我们想要的.

我知道的解决方案是创建一个新模块c.py并在其中定义Err类.然后a.py和b.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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读