# encoding: utf-8
import logging
ERROR_NOT_FOUNDED_FILE = "error_not_founded_file"
class GeneralError(Exception):
def __init__(self, value, description):
print("GeneralError __init__")
self.value = value
self.description = description
def __repr__(self):
print("__repr__")
return "<{} {}:{}>".format(self.__class__.__name__, self.value, self.description)
def __str__(self):
print("__str__")
return "<{} {}:{}>".format(self.__class__.__name__, self.value, self.description)
class FileError(GeneralError):
def __init__(self, description):
super(FileError, self).__init__(ERROR_NOT_FOUNDED_FILE, description)
def __repr__(self):
return super(FileError, self).__repr__() # 不规范
def __str__(self):
super(FileError, self).__str__() # 会报错
try:
raise FileError('file error')
except Exception as e:
logging.info(f"exec error: {e}")
print("补救措施!")
执行结果如下:
错误:
__str__ returned non-string (type NoneType) 可以看出,e返回了None。
debug:
def __str__(self):
super(FileError, self).__str__() # 调用了,父类的__str__函数,没有返回(也可以理解为返回了None)。
logging.info(f"exec error: {e}") # 调用了FileError().__str__,没有返回值,自然就报错了。
修复:
def __str__(self):
return super(FileError, self).__str__() # 调用了,父类的__str__函数,返回执行结果。
或者
不实现重写__str__。
那么正常的代码应该是:
# encoding: utf-8
import logging
ERROR_NOT_FOUNDED_FILE = "error_not_founded_file"
class GeneralError(Exception):
def __new__(cls, *args, **kwargs):
print("GeneralError __new__")
return super(GeneralError, cls).__new__(cls)
def __init__(self, value, description):
print("GeneralError __init__")
self.value = value
self.description = description
def __repr__(self):
print("__repr__")
return "<{} {}:{}>".format(self.__class__.__name__, self.value, self.description)
def __str__(self):
print("__str__")
return "<{} {}:{}>".format(self.__class__.__name__, self.value, self.description)
class FileError(GeneralError):
def __init__(self, description):
super(FileError, self).__init__(ERROR_NOT_FOUNDED_FILE, description)
def __repr__(self):
return super(FileError, self).__repr__()
# 我选择不重写!!! 唯一的修改
# def __str__(self):
# super(FileError, self).__str__()
try:
raise FileError('file error')
except Exception as e:
logging.info(f"exec error: {e}")
print("补救措施!")
当然,这个环境里,代码能跑了。不过,能跑是能跑,有一处不规范
def __repr__(self):
print("__repr__")
return "<{} {}:{}>".format(self.__class__.__name__, self.value, self.description)
官方文档对于__repr__的解释是(repr会调用对象的__repr__):
def repr(obj): # real signature unknown; restored from __doc__ """ Return the canonical string representation of the object. For many object types, including most builtins, eval(repr(obj)) == obj. """ pass
很显然:
err = FileError("file error") eval(repr(err)) == err File "E:/coding/hello.py", line 53, in <module> eval(repr(err)) == err File "<string>", line 1 <FileError error_not_founded_file:file error> ^ SyntaxError: invalid syntax
所以,要修改代码为:
def __repr__(self): print("__repr__") return "{}('{}')".format(self.__class__.__name__, self.description)
那么,最终的代码应该是:
# encoding: utf-8 import logging ERROR_NOT_FOUNDED_FILE = "error_not_founded_file" class GeneralError(Exception): def __new__(cls, *args, **kwargs): print("GeneralError __new__") return super(GeneralError, cls).__new__(cls) def __init__(self, value, description): print("GeneralError __init__") self.value = value self.description = description def __repr__(self): print("__repr__") return "{}('{}')".format(self.__class__.__name__, self.description) # 第一处修改: 返回字符串格式修改 def __str__(self): print("__str__") return "<{} {}:{}>".format(self.__class__.__name__, self.value, self.description) class FileError(GeneralError): def __init__(self, description): super(FileError, self).__init__(ERROR_NOT_FOUNDED_FILE, description)
# 第二处修改:不重写父类方法
# def __repr__(self): # return super(FileError, self).__repr__() # def __str__(self): # super(FileError, self).__str__() try: raise FileError('file error') except Exception as e: logging.info(f"exec error: {e}") print("补救措施!") err = FileError("file error") eval(repr(err)) == err
浙公网安备 33010602011771号