出现__repr__方法无法自动为Exception类调用

时间:2019-05-07 13:09:45

标签: python python-3.x

有人告诉我,如果未创建obj的__str__方法,但是创建了__repr__,那么打印obj将调用__repr__。对于普通类来说,这似乎是正确的,但是当我在Exception的子类上尝试时,奇怪的是__repr__没有被调用,有人可以解释为什么吗?

这是一个例子

class BoringError(Exception):
  def __init__(self):
    self.purpose = "Demonstration"
    self.boringLevel = 10
  def __repr__(self):
    return "I'm a message for developer"

 try: 
   if 1 != 2:
    raise BoringError 
 except BoringError as e:
   print(e.boringLevel)
   print(e)

class Tree:
  def __repr__(self):
    return "I love water"

AVL = Tree()
print(AVL)

该程序产生以下结果

10

I love water

代替

10
I'm a message for developer
I love water

2 个答案:

答案 0 :(得分:4)

__repr__仅在e.__str__解析为object.__str__时调用,该定义基本上像

def __str__(self):
    return self.__repr__()

在您的情况下,永远不会调用object.__str__,因为e.__str__解析为Exception.__str__,而 not 不会调用__repr__的任何定义。比较:

>>> e = Exception("hi")
>>> print(e)
hi
>>> str(e)
'hi'
>>> repr(e)
"Exception('hi')"

Tree.__str__未定义,因此AVL.__str__ 解析为object.__str__,因此调用了Tree.__repr__

答案 1 :(得分:3)

打印异常时,__str__称为__repr__。参见handling exception documentation

  

except子句可以在异常名称后指定一个变量。变量绑定到具有存储在instance.args中的参数的异常实例。 为方便起见,异常实例定义了__str__(),因此可以直接打印自变量,而不必引用.args 。在引发异常之前,可以先实例化异常,然后根据需要向其添加任何属性。

请考虑以下内容:

try:
    raise NameError('HiThere')
except NameError as e:
    print(e)

调用print(e)时,实例e具有一个__str__方法,该方法返回其创建时所使用的参数,在这种情况下为字符串'HiThere'

这就是您可以使用print(e)而不是显式使用print(e.args)的方式。

在您的情况下,没有任何参数传递给BoringError,因此print(e)打印一个空字符串。

使用以下方法覆盖__str__方法:

 def __str__(self):
     return "I'm a message for developer"

达到预期的结果。