Discuss / Python / 我来捋捋这个过程,希望大家指正

我来捋捋这个过程,希望大家指正

Topic source

董DHH董

#1 Created at ... [Delete] [Delete and Lock User]
def foo(s):
    n = int(s)
    if n==0:
        raise ValueError('invalid value: %s' % s)
    return 10 / n

def bar():
    try:
        foo('0')
    except ValueError as e:
        print('ValueError!')
        raise

bar()

这段代码我的理解是: 1)bar()开始调用 2)foo('0')语句执行 3)进入foo()函数中,执行到语句raise ValueError() 4)由于foo()函数抛出异常,因此回到调用方bar() 5)接下来bar()函数捕获这个异常,打印ValueError! 6)然后bar()又抛出当前异常,交由foo()处理,随即foo()打印invalid value :0

请各位大神指点,我是按照打印的结果推理的,我比较纠结的是第6步,不知道理解的对不,由于bar()自己不能处理当前异常又抛出,被foo()捕获,为什么是foo()捕获呢?不是说会被上级捕获吗?foo()也不是bar()的上级啊,哪位大神会?

董DHH董

#2 Created at ... [Delete] [Delete and Lock User]

一句话总结:想知道foo()是不是bar()的顶层调用者,为什么?为什么bar()抛出异常之后会交由foo()处理

fhfuih

#3 Created at ... [Delete] [Delete and Lock User]

bar()的上级确实不是foo(),是主程序,foo()也不会捕获到重新跑出的异常。如果把bar()那一句放在try里面,就会重新接收到错误了。

我觉得你第六步搞错了,在到bar except发现错误之后,执行完print“error”后,直接raise抛出错误,不会再返回FOO()。如果bar()之后还有其他代码应该会继续执行。

BIN6167

#5 Created at ... [Delete] [Delete and Lock User]

我也是个初学者,我理解为bar()函数在执行时时捕获到了foo('0')抛出的ValueError之后打印,又继续执行raise,此时Python解释器自行去捕获错误,捕获到的错误在foo函数内已经有捕获到了,会抛出。 例子就是定义一个继承父类错误的类,定义foo函数内能捕获到类的一个实例,这样raise抛出的就是一个错误实例了。

BIN6167

#6 Created at ... [Delete] [Delete and Lock User]

补充一下,应该是raise抛出后会一层一层往上扔,在哪一层有捕获到结果会抛出,如果都没有捕获到错误会在内部捕获错误再抛出。

儒生脱尘

#7 Created at ... [Delete] [Delete and Lock User]

我觉得你理解的不对。你看我的代码:

class TestError(ValueError):
    pass
def foo(s):
    n = int(s)
    if n==0:
        raise TestError('invalid value: %s' % s)
    return 10 / n

def bar():
    try:
        foo('0')
    except TestError as e:
        print('TestError!')
        #raise

bar()

1.bar()调用,函数开始执行,依次try:-->foo('0')-->调用foo,参数'0'

2.foo('0')开始执行,依次n=int(s)-->if n==0-->满足条件-->抛出错误raise TestError('invalid value: %s' % s)

3.foo('0')此时抛出了一个错误,但是raise只是抛出,并不会在窗口中打印出来。抛出到它的上级调用者bar()中的try中

4.try..except捕获到foo抛出的错误。except对错误类型就行对比-->找到此类型错误的处理信息TestError-->错误进行处理-->执行语句print('TestError!')-->错误再次抛出-->抛出到上级 5.上级中无try..except捕获并处理错误的语句,错误信息在窗口中打印出来。

如果在bar()处理错误中不抛出错误:

class TestError(ValueError):
    pass
def foo(s):
    n = int(s)
    if n==0:
        raise TestError('invalid value: %s' % s)
    return 10 / n

def bar():
    try:
        foo('0')
    except TestError as e:
        print('TestError!')

bar()

运行结果只有一句:

TestError!

foo('0')抛出错误后,错误被捕获并处理,如果不主动抛出,默认错误已处理。

Seaphyr

#8 Created at ... [Delete] [Delete and Lock User]

楼上思路跟我一样,资次资次。

_Wjian_

#9 Created at ... [Delete] [Delete and Lock User]

@儒生脱尘 正解


  • 1

Reply