好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

python动态捕获异常

在讨论动态捕获异常时让我大吃一惊的是,可以让我找到隐藏的Bug和乐趣...

17 POP_TOP

18 POP_TOP

19 POP_TOP

5 20 LOAD_CONST 1 ('bad')

23 PRINT_ITEM

24 PRINT_NEWLINE

25 JUMP_FORWARD 6 (to 34)

>> 28 END_FINALLY

7 >> 29 LOAD_CONST 2 ('good')

32 PRINT_ITEM

33 PRINT_NEWLINE

>> 34 LOAD_CONST 0 (None)

37 RETURN_VALUE

这显示出了我原来预期的问题(issue). 异常处理"看起来"完全是按照Python内部机制在运行. 这一步完全没有必要知道关于后续的异常“捕获”语句, 并且如果没有异常抛出它们将被完全忽略了.SETUP_EXCEPT并不关心发生了什么, 仅仅是如果发生了异常, 第一个处理程序应该被评估,然后第二个,以此类推.

每个处理程序都有两部分组成: 获得一个异常的规则, 和刚刚抛出的异常进行对比. 一切都是延迟的, 一切看起来正如对你的逐行的代码的预期一样, 从解释器的角度来考虑. 没有任务聪明的事情发生了,只是突然使得它看起来非常聪明.

总结

虽然这种动态的异常参数让我大吃一惊, 但是这当中包含很多有趣的应用. 当然去实现它们当中的许多或许是个馊主意,呵呵

有时并不能总是凭直觉来确认有多少Python特性的支持 - 例如 在类作用域内 表达式和声明都是被显式接受的, (而不是函数, 方法, 全局作用域),但是并不是所有的都是如此灵活的. 虽然(我认为)那将是十分美好的, 表达式被禁止应用于装饰器 - 以下是Python语法错误:

@(lambda fn: fn)

def x():

pass

这个是尝试动态异常参数通过给定类型传递给第一个异常的例子, 静静的忍受重复的异常:

>>> class Pushover(object):

... exc_spec = set()

...

... def attempt(self, action):

... try:

... return action()

... except tuple(self.exc_spec):

... pass

... except BaseException as e:

... self.exc_spec.add(e.__class__)

... raise

...

>>> pushover = Pushover()

>>>

>>> for _ in range(4):

... try:

... pushover.attempt(lambda: 1 / 0)

... except:

... print ("Boo")

... else:

... print ("Yay!")

Boo

Yay!

Yay!

Yay!

查看更多关于python动态捕获异常的详细内容...

  阅读:47次