在Python中实现`Exception .__ str __()' [英] Implementation of `Exception.__str__()` in Python

查看:694
本文介绍了在Python中实现`Exception .__ str __()'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从来没有完全理解Python中的异常处理(或任何一种诚实的语言)。我正在尝试使用自定义异常,并发现以下行为。

  class MyError(Exception):
def __init __


我= MyError(iiiiii)
打印(我)

输出:

  iiiiii 

我假设 print()调用异常.__ str __()



基础类如何异常知道打印 IIIIII iiiiii通过参数传递给 MyError 的构造函数, code>,但任何不存储在 MyError 中的任何地方!



此外, MyError 的构造函数不会调用其超类(异常)构造函数。那么,如何 print(me) print iiiiii

解决方案

在Python 3中, BaseException 类有一个 __ new __ 将参数存储在 self.args 中:

 >> ; me.args 
('iiiiii',)

你没有覆盖 __ new __ 方法,只有 __ init __ 。您需要覆盖 以完全阻止从 self.args 设置,因为两个实现都很乐意设置该属性:

 >>> class MyError(Exception):
... def __new __(cls,* args,** kw):
...返回super().__新__(cls)#忽略args和kwargs!
... def __init __(self,* args,** kw):
... super().__ init __()#再次忽略args和kwargs
...
>>> me = MyError(iiiiii)
>>>我
MyError()
>>> print(me)

>>> me.args
()

在Python 2中,异常不实现 __ new __ ,您的样本将不会打印任何内容。有关 __ new __ 方法的原因,请参阅问题#1692335 加入;基本上是为了避免像你这样的问题,其中 __ init __ 方法也不会调用 super().__ init __()。 p>

请注意, __ init __ 不是一个构造函数;该实例已经在该时间之前由 __ new __ 构建。 __ init __ 仅仅是初始化器


I've never fully understood exception handling in Python (or any language to be honest). I was experimenting with custom exceptions, and found the following behaviour.

class MyError(Exception):
    def __init__(self, anything):
        pass

me = MyError("iiiiii")
print(me)

Output:

iiiiii

I assume that print() calls Exception.__str__().

How does the base class Exception know to print iiiiii? The string "iiiiii" was passed to the constructor of MyError via the argument anything, but anything isn't stored anywhere in MyError at all!

Furthermore, the constructor of MyError does not call its superclass's (Exception's) constructor. So, how did print(me) print iiiiii?

解决方案

In Python 3, the BaseException class has a __new__ method that stores the arguments in self.args:

>>> me.args
('iiiiii',)

You didn't override the __new__ method, only __init__. You'd need to override both to completely prevent from self.args to be set, as both implementations happily set that attribute:

>>> class MyError(Exception):
...     def __new__(cls, *args, **kw):
...         return super().__new__(cls)  # ignoring args and kwargs!
...     def __init__(self, *args, **kw):
...         super().__init__()           # again ignoring args and kwargs
...
>>> me = MyError("iiiiii")
>>> me
MyError()
>>> print(me)

>>> me.args
()

In Python 2, exceptions do not implement __new__ and your sample would not print anything. See issue #1692335 as to why the __new__ method was added; basically to avoid issues like yours where the __init__ method does not also call super().__init__().

Note that __init__ is not a constructor; the instance is already constructed by that time, by __new__. __init__ is merely the initialiser.

这篇关于在Python中实现`Exception .__ str __()'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆