提出问题

当我们自定义一个类时,打印这个类对象或者在交互模式下直接输入这个类对象按回车,默认显示出来的信息好像用处不大。如下所示

In [1]: class People:
...: def __init__(self, name, sex):
...: self.name = name
...: self.sex = sex
...: In [2]: p = People('xiaoming', 'male') In [3]: p
Out[3]: <__main__.People at 0x7fd0df745400> In [4]: print(p)
<__main__.People object at 0x7fd0df745400>

可以发现,两种方式显示出来的信息都是对象所属类的名称以及对象所在的地址,而很多时候这不是我们想要的信息,此时我们可以通过重写__str__和__repr__方法来定制我们想要的信息。

__str__与__repr__简单介绍

__str__ 和 __repr__ 方法,是自定义类的字符串描述,当我们打印或查看某个对象时,最终看到的结果是这两个方法的返回值。这两个方法返回的都是字符串,但是什么时候调用__str__?什么时候调用__repr__?我们看下面的例子

类中只重写了__str__方法

In [1]: class A:
...: def __str__(self):
...: return '__str__'
...: In [2]: a = A() In [3]: a
Out[3]: <__main__.A at 0x7ffb3f2ba048> In [4]: print(a)
__str__

在交互模式下,直接输入对象再回车,返回的结果与原来一样;但是打印对象时,触发了__str__方法。

类中只重写了__repr__方法

In [1]: class B:
...: def __repr__(self):
...: return '__repr__'
...: In [2]: b = B() In [3]: b
Out[3]: __repr__ In [4]: print(b)
__repr__

在交互模式下,直接输入对象再回车以及打印对象都触发了__repr__方法。

类中重写了__str__与__repr__方法

In [1]: class C:
...: def __str__(self):
...: return '__str__'
...: def __repr__(self):
...: return '__repr__'
...: In [2]: c = C() In [3]: c
Out[3]: __repr__ In [4]: print(c)
__str__

在交互模式下,直接输入对象再回车,触发了__repr__方法;打印对象触发__str__方法。

总结一下,当我们直接查看对象(输入对象再回车)时,无论怎样触发的都是__repr__方法;如果自定义类中没有重写这个方法,我们知道Python3中都是新式类,即默认都继承了object类,那么此时就会调用object中的__repr__方法。当我们打印对象时,大多数情况触发的都是__str__方法,但当自定义类中只重写了__repr__方法时,会触发__repr__方法。

str()和repr()函数

str()默认触发__str__方法,repr()默认触发__repr__方法,触发的机制与上述一样;另外,列表、字典等容器总是会触发__repr__方法,代码示例如下:

# 类中只重写了__str__方法
In [5]: str(a)
Out[5]: '__str__' In [6]: repr(a)
Out[6]: '<__main__.A object at 0x7ffb3f2ba048>' # 类中只重写了__repr__方法
In [5]: str(b)
Out[5]: '__repr__' In [6]: repr(b)
Out[6]: '__repr__' # 类中重写了__str__与__repr__方法
In [5]: str(c)
Out[5]: '__str__' In [6]: repr(c)
Out[6]: '__repr__' # 列表、字典等容器总是会触发__repr__方法
In [53]: print([a])
[<__main__.A object at 0x7ffb3f2ba048>] In [7]: str([c])
Out[7]: '[__repr__]' In [8]: repr([c])
Out[8]: '[__repr__]' In [9]: [c]
Out[9]: [__repr__] In [10]: print([c])
[__repr__]

__str__与__repr__的本质区别

那__str__与__repr__的本质区别到底是什么呢? 先看官方描述

  • __str__: Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object.
  • __repr__: Called by the repr() built-in function to compute the “official” string representation of an object. This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.

总结一下,__str__是一个对象的非正式的、易于阅读的字符串描述,当类str实例化( str(object) )时会被调用,以及会被内置函数format()和print()调用;__repr__是一个对象的官方的字符串描述,会被内置函数repr()方法调用,它的描述必须是信息丰富的和明确的。也就是说__str__返回的结果可读性强,__repr__返回的结果更加准确。再看一个例子

In [1]: import datetime                                                         

In [2]: d = datetime.datetime.now()                                             

In [3]: str(d)
Out[3]: '2019-08-24 08:12:17.942242' # 可读性强 In [4]: repr(d)
Out[4]: 'datetime.datetime(2019, 8, 24, 8, 12, 17, 942242)' # 信息更加丰富和准确

总结

  • 在自定义类中,可以通过重写__str__和__repr__方法来定制类对象到字符串的转化。
  • 一般情况下,推荐至少添加一个 __repr__ 方法来定制对象到字符串的自定义转化,__str__ 是可选的。因为默认情况下,在需要却找不到 __str__ 方法的时候,会自动调用 __repr__ 方法。
  • __str__方法的目标在于可读性,__repr__方法的目标在于准确性。
定义
形容词suitable or fit to be printed or published.
示例
The only comment I can make to reply to that is not printable .

python中魔法方法__str__与__repr__的区别的更多相关文章

  1. python中魔法方法__init__,__str__,__del__的详细使用方法

    1. python中的魔法方法, 类似__init__, __str__等等,这些内置好的特定的方法进行特定的操作时会自动被调用 2. __init__的使用方法 class 类名(object):  ...

  2. python 的特殊方法 __str__和__repr__

    __str__和__repr__ 如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class Person(object): def __init__(self, name, ...

  3. python中魔法方法(持续更新)

    1.对于一个自定义的类,如果实现了 __call__ 方法,那么该类的实例对象的行为就是一个函数,是一个可以被调用(callable)的对象.例如: class Add: def __init__(s ...

  4. python中__str__与__repr__的区别

    __str__和repr __str__和__repr__都是python的内置方法,都用与将对象的属性转化成人类容易识别的信息,他们有什么区别呢 来看一段代码 from math import hy ...

  5. python之魔法方法介绍

    1.1. 简介 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加“魔法”的特殊方法. 它们经常是两个下划线包围来命名的(比如 __init__ , __lt__ ) ...

  6. Python中sorted()方法的用法

    Python中sorted()方法的用法 2012-12-24 22:01:14|  分类: Python |字号 订阅 1.先说一下iterable,中文意思是迭代器. Python的帮助文档中对i ...

  7. Python中sorted()方法

    Python中sorted()方法的用法 1.先说一下iterable,中文意思是迭代器. Python的帮助文档中对iterable的解释是:iteralbe指的是能够一次返回它的一个成员的对象.i ...

  8. Python中__init__方法介绍

    本文介绍Python中__init__方法的意义.         __init__方法在类的一个对象被建立时,马上运行.这个方法可以用来对你的对象做一些你希望的 初始化 .注意,这个名称的开始和结尾 ...

  9. Python中strip方法的妙用

    [开胃小菜] 当提到python中strip方法,想必凡接触过python的同行都知道它主要用来切除空格.有下面两种方法来实现. 方法一:用内置函数 #<python> if __name ...

随机推荐

  1. 11.Python变量及其使用

    无论使用什么语言编程,其最终目的都是对数据进行处理.程序在编程过程中,为了处理数据更加方便,通常会将其存储在变量中. 形象地看,变量就像一个个小容器,用于“盛装”程序中的数据.除了变量,还有常量,它也 ...

  2. sqli-labs(46)

    0X01首先我们先来看一下源码 发现查询语句变成了 order by  参数也变成了 sort 看看是什么样的 ()首先看看本关sql语句 $sql = "SELECT * FROM use ...

  3. Java内存模型之可见性问题

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 前言 之前的文章中讲到,JMM是内存模型规范在Java语 ...

  4. 【每日一包0012】to-camel-case,to-no-case,to-space-case

    github地址:https://github.com/ABCDdouyaer/a_pack_per_day_NO.1 to-camel-case 将被其他符号分割的字符串转换为驼峰形式的字符串 用法 ...

  5. C++入门经典-例3.2-根据分数判断是否优秀

    1:代码如下: // 3.2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...

  6. 第十二周Java学习总结

    学习总结: 本周主要学习了其他容器和事件处理 1.窗体事件(WindowListener)常用接口方法voidwindowActivated/windowDeactivated(WindowEvent ...

  7. python3笔记五:while语句

    一:学习内容 while语句 while-else语句 while语句练习 二:while语句 1. 格式 while 表达式:    语句 2.逻辑 当程序执行到while语句时,首先计算表达式的值 ...

  8. webpack 第二部分

    默认根目录 当前项目 修改目录 devServer devServer:{ open:true, //自动打开浏览器 port:3000, // 端口 contentBase:"dist&q ...

  9. Linux高级调试与优化——内存泄漏实战分析

    最近在整理Linux调试方面的文档,正好碰到了一个内存泄漏踩栈的问题,借此机会记录一下分析过程. 首先,发现问题之后,赶紧看一下产生coredump文件没有,果不其然,产生了coredump,果断上g ...

  10. 如何解决Struts2和Servlet共存问题

    我之前用Servlet写过二维码扫描登录,结果把它整合到ssh框架中,发现Servlet和Struts存在共存问题,这是因为当我们在页面在请求应用时,struts2将会截获所有请求,对于servlet ...