# 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

python-魔法函数-__str__ __repr__ 的一次异常的更多相关文章

  1. python魔法函数__dict__和__getattr__的妙用

    python魔法函数__dict__和__getattr__的妙用 __dict__ __dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值. 既然__dict__是个字典那么我们就 ...

  2. Python魔法函数与两比特量子系统模拟

    技术背景 本文主要涵盖两个领域的知识点:python的魔法函数和量子计算模拟,我们可以通过一个实际的案例来先审视一下这两个需求是如何被结合起来的. 量子计算模拟背景 ProjectQ是一个非常优雅的开 ...

  3. 复习python的__call__ __str__ __repr__ __getattr__函数 整理

    class Www: def __init__(self,name): self.name=name def __str__(self): return '名称 %s'%self.name #__re ...

  4. Python魔法函数

    python中定义的以__开头和结尾的的函数.可以随意定制类的特性.魔法函数定义好之后一般不需要我们自己去调用,而是解释器会自动帮我们调用. __getitem__(self, item) 将类编程一 ...

  5. python基础---- __getattribute__----__str__,__repr__,__format__----__doc__----__module__和__class__

    目录: 一. __getattribute__ 二.__str__,__repr__,__format__ 三.__doc__ 四.__module__和__class__ 一. __getattri ...

  6. python魔法函数之__getattr__与__getattribute__

    getattr 在访问对象的属性不存在时,调用__getattr__,如果没有定义该魔法函数会报错 class Test: def __init__(self, name, age): self.na ...

  7. python魔法函数(二)之__getitem__、__len__、__iter__

    魔法函数会增强python类的类型,独立存在 __getitem class Company: def __init__(self, employees): self.employees = empl ...

  8. python魔法函数的一些疑问

    看了魔法函数,有一点疑问.1中需要用self.word才能执行,而2直接用self就可以执行.而1中Word继承了int基本类型,但在__new__时并没有什么卵用.当用 Word(“123”)来实例 ...

  9. raindi python魔法函数(一)之__repr__与__str__

    __repr__和__str__都是python中的特殊方法,都是用来输出实例对象的,如果没有定义这两个方法在打印的时候只会输出实例所在的内存地址 这种方式的输出没有可读性,并不能直观的体现实例.py ...

  10. Python——详解__str__, __repr__和__format__

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第10篇文章,我们来聊聊Python当中的类. 打印实例 我们先从类和对象当中最简单的打印输出开始讲起,打印一个实例 ...

随机推荐

  1. Python中的容器、迭代器、生成器

    容器是一系列元素的集合,str.list.set.dict.file.sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为可迭代对象. 可迭代对象实现 ...

  2. Java方法之什么是方法?

    方法详解 何谓方法? System.out.println(),那么它是什么呢? 1.System:类 2.out:对象 3.println():方法 Java方法是语句的集合,它们在一起执行一个功能 ...

  3. 使用骨架创建maven的web工程 maven工程servlet实例之间指定web资源包 实例之导入项目依赖的jar包 maven工程servlet实例之jar包冲突解决

     使用骨架创建maven的web工程 操作一样把勾进行勾选找到webapp选项 下一步创建就行 创建好会有显示 目录结构其余的都需要自己手动补齐 有小蓝点的才是一个web项目, 如果上面都正确的话没有 ...

  4. .NET Core 3.0 WebApi 使用Swagger

    1.安装指定版本: Swashbuckle.AspNetCore 5.0.0-rc4(目前稳定版本4.0.1在AspNetCore3.0中会报错误) 2.后台C#代码要严格格式必须加[HttpPost ...

  5. 构建一个自己的CocoaPods库

    1.首先去github 创建一个项目 .然后将你的代码传到github 2.终端 进入项目根目录 生成podspec pod spec create SJTestPod 注意生成的pod一定要唯一.不 ...

  6. Github页面图片加载失败

    Window系统下 还可以使用ipconfig/flush对本地DNS缓存进行一次刷新,如果遇到网络异常,可能是DNS缓存的问题,刷新一下,步骤. windows开始→运行→输入:CMD 按回车键,打 ...

  7. Edge浏览器相关

    Ctrl+T 新建页面 Ctrl+W 关闭页面 不可复制的页面,前加read: 若是不可访问 变read://http:// 阅读可翻译,也可有图片字典 还可用插件: 截图软件:Snipaste  微 ...

  8. FastReport报表金额数字转大写问题

    在使用FastReport报表打印的时候涉及到财务结算金额时,会用到大写,系统保存的都为数字,将数字转换为大写没有默认的系统内置函数,经过查阅资料,可通过对FastReport的页面设计代码修改实现: ...

  9. Flutter showModalBottomSheet 自适应高度

    showModalBottomSheet( context: context, shape: const RoundedRectangleBorder( borderRadius: BorderRad ...

  10. 记一次pushgateway因文件句柄数太多未回收的问题

    1. 问题描述: Flink上报metrics到pushGateway,pushGwateway因打开在多文件而拒绝Flink TaskManager上报数据的连接.查看pushGateway的日志如 ...