提升之后更改异常的类

时间:2016-05-06 20:15:02

标签: python multithreading exception cpython

我编写了以下代码,它引发了一个异常,而一个线程不断更改引发异常的类:

import threading
import time

class Foo(Exception):
    pass

class Bar(Exception):
    pass

class MyExc(Exception):
    pass

b = True
e = MyExc()
def mess():
    global e
    global b
    time.sleep(0.00000000000000000000001)
    while b:
        e.__class__ = Bar
        e.__class__ = Foo
threading.Thread(target=mess).start()

try:
    try:
        try:
            try:
                try:
                    raise e
                except Foo:
                    print(1)
            except Foo:
                print(2)
        except Foo:
            print(3)
    except Foo:
        print(4)
except Foo:
    print(5)
except Bar:
    print('bar')
except MyExc:
    print('myexc')

b = False

使用CPython时,不同的时间使其打印1barmyexc(您可能需要稍微调整一下睡眠时间以获得其中的三个)。但绝不是其他数字。

为什么呢?是因为CPython在展开堆栈时没有运行其他线程吗?

1 个答案:

答案 0 :(得分:0)

我怀疑发生的事情是,当你启动你的线程时,它会在它到达raise命令之前改变'e'的类型。一旦它到达raise命令,就会捕获它的当前类型的异常,它将是MyExc,Foo或Bar,然后通过异常处理逻辑。

如果你想更多地玩它,你可以在try / except逻辑中重新加入异常。类似的东西:

try:
    try:
        try:
            raise e
        except:
            print(1)
            raise
    except:
        print(2)
        raise
 except:
     print(3)
     raise