前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python Every Class Needs a __repr__

Python Every Class Needs a __repr__

作者头像
coders
发布2019-05-25 16:45:29
3650
发布2019-05-25 16:45:29
举报
文章被收录于专栏:coder修行路

一、思考

当我们在Python中定义一个类的时候,如果我们通过print打印这个类的实例化对象,或者我们直接输入这个类实例化对象会返回怎么样的结果,如下代码:

代码语言:javascript
复制
>>> 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的方式去控制不同情况下将对象进行转换为字符串,也就是控制其显示的结果内容。 我们把上面的代码进行更改的内容如下:

代码语言:javascript
复制
>>> 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方法,如我们进行如下操作时:

代码语言:javascript
复制
>>> 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 其实是非常类似的,只不过用的场景不同,将上面的代码进行调整:

代码语言:javascript
复制
>>> 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存到列表里, 然后打印查看如下:

代码语言:javascript
复制
>>> print([tom])
[__repr__: people name is Tom]
>>>

为了验证我们到底应该怎么用这两个方法,毕竟这两个方法的作用还是非常类似的,我们可以通过Python标准库来验证一下,跟着标准库走总不会有错

代码语言:javascript
复制
>>> 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方法去掉之后的结果:

代码语言:javascript
复制
>>> 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类时的代码:

代码语言:javascript
复制
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)的返回结果

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-03-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、思考
  • 二、__str__ vs __repr__
  • 三、Why Every Class Needs a repr
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档