Python Exception 错误信息输出机理

本文解析了Python中异常的工作原理,展示了如何使用内置异常机制,并自定义异常类来改善错误信息的输出。

当遇到一个如下的exception时,最后一行错误信息是从何而来的呢?

>>> 2 / 0
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

其机理可用一句话描述:ExceptionObject.__class__.__name__ + ': ' + ExceptionObject.__str__()

默认情况下,Exception实例初始化时会将参数赋给属性args,实例方法__str__输出args。例如:

>>> try:
...     raise Exception("foo", "bar")
... except Exception as e:
...     print e.args
...     print e.__str__()
...     raise
... 
('foo', 'bar')
('foo', 'bar')
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: ('foo', 'bar')

当然,我们可以定义自己的__init____str__。例如:

>>> class FooException(Exception):
...     def __init__(self, errno, message):
...             self._errno = errno
...             self._message = message
...     def __str__(self):
...             return repr(self._message)
...
>>> raise FooException(404, "Web Page not found")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.FooException: 'Web Page not found'

参考资料:
1. Python Official Documents: Errors and Exceptions

### Python中`yield`关键字的工作原理 #### `yield`与迭代器协议 在Python中,`yield`用于定义生成器函数。当调用这样的函数时,并不会立即执行其中的代码,而是返回一个生成器对象。这个对象遵循迭代器协议——即实现了`__next__()`方法(在Python 2.x版本里是`.next()`),每次请求下一个值的时候才继续运行直到遇到`yield`表达式并暂停,同时把当前产生的值得交给外部环境。 ```python def simple_generator(): yield "first" yield "second" yield "third" gen = simple_generator() print(next(gen)) # 输出 first print(next(gen)) # 输出 second ``` #### 状态保存机制 每当执行到含有`yield`语句的地方,函数的状态会被完整地保存下来,包括局部变量、指令指针等信息[^2]。这意味着即使离开了该作用域之后再次进入也不会丢失之前的信息;相反,可以从上次离开的位置重新开始计算过程。这种特性允许创建复杂的逻辑流程而无需担心中间结果的存储问题。 #### 暂停与恢复操作 `yield`不仅能够传递数据给调用者,还可以接收来自外界传入的消息或参数。例如,在某些情况下可能希望改变内部行为模式或是提前终止整个序列生产活动: ```python def echo(value=None): while True: received = (yield value) if received is not None: break e = echo(10) print(e.send(None)) # 启动生成器, 输出 10 print(e.send(20)) # 发送新值给生成器, 此处将结束循环, 不再有输出 ``` 上述例子展示了如何利用`send()`方法向正在等待输入的生成器发送新的值,从而影响其后续的行为路径。 #### 错误处理能力 除了基本的功能外,`yield`还支持异常捕获和清理工作。如果发生错误,则可以通过特定的方式通知生成器以便采取适当措施加以应对。比如使用`throw()`来注入自定义类型的Exception实例,亦或是借助于`close()`来进行优雅退出前后的资源释放动作[^3]。 ```python def careful_gen(): try: yield 'start' raise ValueError('something wrong happened') yield 'never reached' finally: print("Cleaning up resources") cg = careful_gen() print(next(cg)) try: cg.throw(ValueError) except StopIteration: pass finally: cg.close() # Cleaning up resources ``` 以上就是关于Python中`yield`关键字及其背后运作机理的大致描述。通过这种方式编写的程序往往具有更高的性能表现力以及更好的内存利用率,尤其是在面对大规模连续性任务处理需求之时尤为明显。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值