python循环导入和定义异常类

时间:2015-04-26 07:35:47

标签: python

我知道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, in <module>
    b.f()
  File "b.py", line 7, in f
    raise Err()
a.Err

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

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

是否有解决方案允许我们在Err中定义a.py?请注意,问题不仅仅是异常类,根据我们在代码中使用对象的方式,任何python类都可能属于这个坑。

1 个答案:

答案 0 :(得分:1)

当您在模块末尾添加process.on('SIGTERM', () => { if (client) { console.log('Ending CACHE connection'); client.quit(); } console.log('Closing server...'); app.close(() => { console.log('server was closed!'); process.exit(0); }); }); 时,请参考前面代码中定义的内容,它 与导入和使用模块相同( if __name__ == '__main__':模块不会缓存在__main__中。您可以通过以下修改使第一个示例正常工作:

<强> a.py

sys.modules

输出:

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