Python Every Class Needs a __repr__
一、思考
当我们在Python中定义一个类的时候,如果我们通过print打印这个类的实例化对象,或者我们直接输入这个类实例化对象会返回怎么样的结果,如下代码:
>>> class People(object):
... def __init__(self, name, age):
... self.name = name
... self.age = age
...
>>> tom = People("Tom", 23)
>>> print(tom)
<__main__.People object at 0x00000000027A7160>
>>> tom
<__main__.People object at 0x00000000027A7160>
>>>
默认情况下,你得到的是一个字符串,其中包含类名和对象实例的id(这是CPython中对象的内存地址),其实有更加Pythonic的方式去控制不同情况下将对象进行转换为字符串,也就是控制其显示的结果内容。 我们把上面的代码进行更改的内容如下:
>>> class People(object):
... def __init__(self, name, age):
... self.name = name
... self.age = age
... def __str__(self):
... return f"people name is {self.name}"
...
>>> tom = People("Tom", 23)
>>> print(tom)
people name is Tom
>>> tom
<__main__.People object at 0x00000000021B7208>
>>>
str 是python的内置方法,并且当你在尝试去吧一个对象转换为一个字符串的时候怎么调用这个str方法,如我们进行如下操作时:
>>> class People(object):
... def __init__(self, name, age):
... self.name = name
... self.age = age
... def __str__(self):
... return f"people name is {self.name}"
...
>>> tom = People("Tom", 23)
>>> print(tom)
people name is Tom
>>> str(tom)
'people name is Tom'
>>> '{}'.format(tom)
'people name is Tom'
>>> tom
<__main__.People object at 0x00000000021E7208>
>>>
二、__str__ vs __repr__
在上面的代码中我们添加了str_方法之后,当我们将对象转换为字符串的时候都会调用str方法,并得到我们自己定义的内容,但是并没有影响到我们在python交互模式下直接输入对象的返回内容。其实
repr 和 str 其实是非常类似的,只不过用的场景不同,将上面的代码进行调整:
>>> class People(object):
... def __init__(self, name, age):
... self.name = name
... self.age = age
... def __str__(self):
... return f"people name is {self.name}"
... def __repr__(self):
... return f"__repr__: people name is {self.name}"
...
>>> tom = People("Tom", 23)
>>> print(tom)
people name is Tom
>>> str(tom)
'people name is Tom'
>>> '{}'.format(tom)
'people name is Tom'
>>> tom
__repr__: people name is Tom
>>>
其实这里也就验证了,在Python的交互模式下,检查一个对象,其实就是在调用对象的repr方法,还有一个你可能没有发现的地方就是当你在list,dict等容器中存储对象的时候,我们打印看到的都是repr的内容,我们把上面的tom存到列表里, 然后打印查看如下:
>>> print([tom])
[__repr__: people name is Tom]
>>>
为了验证我们到底应该怎么用这两个方法,毕竟这两个方法的作用还是非常类似的,我们可以通过Python标准库来验证一下,跟着标准库走总不会有错
>>> import datetime
>>> today = datetime.date.today()
>>> today
datetime.date(2019, 3, 5)
>>> str(today)
'2019-03-05'
>>> repr(today)
'datetime.date(2019, 3, 5)'
>>>
从这个Python标准库的用法,我们也能非常好的理解str方法其实就是为了返回一个人们容易理解的字符串类型的结果,而repr方法更偏向于程序员方便去调试,能从结果中看到更加有用的信息,它甚至包括完整的模块和类
三、Why Every Class Needs a repr
我们先看一下我们将我们上面代码的str方法去掉之后的结果:
>>> class People(object):
... def __init__(self, name, age):
... self.name = name
... self.age = age
... # def __str__(self):
... # return f"people name is {self.name}"
... def __repr__(self):
... return f"__repr__: people name is {self.name}"
...
>>> tom = People("Tom", 23)
>>> print(tom)
__repr__: people name is Tom
>>> str(tom)
'__repr__: people name is Tom'
>>> '{}'.format(tom)
'__repr__: people name is Tom'
>>> tom
__repr__: people name is Tom
>>>
从这里我们发现当当你把对象进行字符串转换的时候,就会先去找str方法,如果没有则再去找repr方法执行
所以还是建议在自己定义的类中都至少有一个repr方法,这样不管在上面情况下,你都能有一个对你来说有用的字符串返回结果,而不再是一个干巴巴的内存地址,所以在最后我们规范一下我们写一个Python类时的代码:
class People(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'people name is {self.name}'
def __repr__(self):
return (f'{self.__class__.__name__}('
f'{self.name!r}, {self.age!r})')
在最后的repr的返回中我们用了!r 这个意味着我们要的repr(self.name) repr(self.age)而不是要str(self.name) str(self.age)的返回结果
Python Every Class Needs a __repr__的更多相关文章
- python中的__str__和__repr__方法
如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class A(object): def __init__(self,name,age): self.name=name se ...
- 第8.15节 Python重写自定义类的__repr__方法
一. 引言 前面两节分别介绍了Python类中的__str__和__repr__方法的作用和语法,所有新式类都支持这两个方法,因为object类实现了这两个方法,但实际上各位开发者在自定义类的过程中, ...
- Python中的魔法函数__repr__和__str__的实质性区别
str 和 repr 方法:是自定义类的字符串描述,这两种都是比较 Pythonic 的方式去控制对象转化为字符串的方式. 调用这两个方法,返回的都是字符串.但是这两个方法又有一些区别 ** 1 两种 ...
- python 中的__str__ 和__repr__方法
看下面的例子就明白了 class Test(object): def __init__(self, value='hello, world!'): self.data = value >> ...
- python 的特殊方法 __str__和__repr__
__str__和__repr__ 如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class Person(object): def __init__(self, name, ...
- 浅谈python中__str__和__repr__的区别
很多时候我们在创建一个类的时候,在终端打印类或者查看的时候一般都不会得到一个太满意的结果 class T: def __init__(self): self.color="red" ...
- Python中自定义类如果重写了__repr__方法为什么会影响到str的输出?
这是因为Python3中,str的输出是调用类的实例方法__str__来输出,如果__str__方法没有重写,则自动继承object类的__str__方法,而object类的__str__方法是调用_ ...
- 利用Python特殊变量__dict__快速实现__repr__的一种方法
在<第8.15节 Python重写自定义类的__repr__方法>.<Python中repr(变量)和str(变量)的返回值有什么区别和联系>.<第8.13节 Pytho ...
- Python基础学习笔记FromImooc.com
1.list L = ['a','a','a','a','a','a3'] L[0] = a L[-1] = a3 添加新元素 L.append('paul') L.insert(-1,'Paul ...
随机推荐
- 负载均衡---ribbon
Ribbon:提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用. 上一篇简单讲解了eureka的使用,这一篇文章基于上一篇的基础上,讲一下springcloud的另一个重要的组 ...
- PHPstorm配置SVN的问题
开始尝试用PHPstorm做项目开发,在集成SVN的时候碰到了问题. 1. PHPstorm Cannot run program "svn" 2. Subversion comm ...
- 洛谷 P2814 家谱(gen)
题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. 输入输出格式 输入格式: 输入由多行组成,首先是一系列有关父子关系的描述,其中每一组 ...
- 考前停课集训 Day2 非
因为太长了 所以一天一天分开发 Day2 昨天晚上没开黑车 没脱衣服就睡了 可能是我难受了…… 新的一天. 早上好. 我没去晨跑,早上先和团长集合了,没看见rkbudlo来 于是就先吃饭了 去机房的时 ...
- 基于Two.js实现的一个小demo,星球环绕动画效果
下面是核心js code HTML就不贴了,需要引入two.js文件: var elem = document.getElementById('draw-animation'); var two = ...
- django中数据库操作有关部分
# >>>>>>>>>>>>>>>>>>>>>>>>&g ...
- Vue(七)发送Ajax请求
发送AJAX请求 1. 简介 vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基于Promise的HTTP请求客户端,用来发送请求,也是vue ...
- JSOUP 乱码处理
JSOUP 支持在请求的时候,传入URL 对象,然后设置编码.如下方式才是正解,设置编码为GBK . doc = Jsoup.parse(new URL(url).openStream(), &qu ...
- LVM原理与实现
一.什么是LVM 不管是使用传统的MBR分区方式或者是GPT的分区方式,在最后数据量逐渐变大的过程中都会出现空间不足的情况,但是若是使用将此分区的数据全部迁移至一个更大空间的磁盘上的迁移时间也是不可想 ...
- c++中函数的参数传递,内联函数和默认实参的理解
1.参数传递 1)函数调用时,c++中有三种传递方法:值传递.指针传递.引用传递. 给函数传递参数,遵循变量初始化规则.非引用类型的形参一相应的实参的副本初始化.对(非引用)形参的任何修改仅作用域局部 ...