BaseException.__str__
可以用一种与python3向后不兼容的方式进行修复,以至少包含异常的类型,但是也许没有人注意到它是一个应该被修复的东西。
目前的实施可追溯到PEP 0352,其中提供了基本原理:
对可以传递的内容没有限制
args
因为向后兼容的原因。但实际上,只应使用单个字符串参数。这使得异常的字符串表示形式保持为关于异常的有用消息,这是人类可读的;这就是为什么
__str__
方法特例长度1
参数
价值观。包括编程信息(例如,错误代码号)应作为单独的属性存储在子类中。
当然,Python本身在许多情况下打破了有用的人类可读消息的这一原则——例如对
KeyError
An error occurred: 42
为什么
str(e)
本质上是
str(e.args)
或
str(e.args[0])
,引发异常的语法,例如
ValueError
>>> raise ValueError, 'x must be positive'
Traceback (innermost last):
File "<stdin>", line 1
ValueError: x must be positive
Python 2.7版
>>> raise ValueError, 'x must be positive'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: x must be positive
同样,在
Python 1.0版
你会赶上火车的
值错误
>>> try:
... raise ValueError, 'foo'
... except ValueError, e:
... print 'Got ValueError', e
在Python2.7中工作不变。
但是内部工作机制发生了变化:在Python1.0.1中,
值错误
是一个
一串
有价值的。。。
'ValueError'
>>> ValueError, type(ValueError)
('ValueError', <type 'string'>)
raise
以字符串作为鉴别器的单个参数或元组:
>>> class MyCustomException:
... pass
...
>>> raise MyCustomException, 'my custom exception'
Traceback (innermost last):
File "<stdin>", line 1
TypeError: exceptions must be strings
>>> raise ValueError, ('invalid value for x', 42)
Traceback (innermost last):
File "<stdin>", line 1
ValueError: ('invalid value for x', 42)
如果你发现这个“例外”
,你得到了什么
e
>>> try:
... raise ValueError, ('invalid value for x', 42)
... except ValueError, e:
... print e, type(e)
...
('invalid value for x', 42) 42 <type 'tuple'>
A
元组
!
让我们试一下密码
:
>>> try:
... raise ValueError, ('invalid value for x', 42)
... except ValueError, e:
... print e, e[1], type(e)
...
('invalid value for x', 42) 42 <type 'exceptions.ValueError'>
tuple
以前和现在都是例外。。。不仅如此
Exception
__str公司__
参数
Python 2.7版
>>> a, b, c = ValueError(1, 2, 3)
>>> print a, b, c
1 2 3
所有这些黑客都是为了保持向后兼容性。
BaseException
PEP 0352
; pep0352最初是在python2.5中实现的。
raise discriminator, (arg, um, ents)
; 以及
except
只能使用
Exception as e
pep0352讨论了放弃对多个参数的支持
基本异常
:
会议决定,最好还是不赞成这一提议
message
属性(并在Python2.7和Python3.0中删除它),并考虑在Python3.0中使用更长期的转换策略,以删除中的多参数支持
宁愿只接受一个论点。因此,消息的引入和最初对
参数
已经收回。
这似乎是对
参数
被遗忘了,因为它仍然存在于python3.7中,并且是
访问给定给许多内置异常的参数的方法。同样地
__str公司__
不再需要委托给args,实际上可以为
BaseException.__repr__
它给出了更好的,明确的表述:
>>> BaseException.__str__(ValueError('foo', 'bar', 'baz'))
"('foo', 'bar', 'baz')"
>>> BaseException.__repr__(ValueError('foo', 'bar', 'baz'))
"ValueError('foo', 'bar', 'baz')"
但没人考虑过。
另请注意
repr
一个例外是有用的-下次尝试打印您的例外与
!r
格式:
print(f'Oops, I got a {e!r}')
结果是
ZeroDivisionError('division by zero',)
正在输出。