Python中字符串的格式化一般使用str和repr,str和repr调用的底层特殊函数是__str____repr__。用示例展示它们之间的区别。

示例1:

>>> import datetime
>>> today = datetime.date.today()
>>> 
>>> today
datetime.date(2017, 12, 30)
>>> repr(today)
'datetime.date(2017, 12, 30)'

>>> print(today)
2017-12-30
>>> str(today)
'2017-12-30'
>>> '{}'.format(today)
'2017-12-30'

>>> print([today, today])
[datetime.date(2017, 12, 30), datetime.date(2017, 12, 30)]

上面这个示例可以看出Python解释器在处理字符串输出的几种方式。值得注意的是最后一个print列表时,打印的元素调用的是__repr__

示例2:

# 没有实现__str__/__repr__
In [1]: class Person:
   ...:     def __init__(self, gender, age):
   ...:         self.gender = gender
   ...:         self.age = age
   ...:

In [2]: person = Person('male', 28)

In [3]: person
Out[3]: <__main__.Person at 0x108c91dd8>

In [6]: print(person)
<__main__.Person object at 0x108c91dd8>


# 实现__repr__
In [11]: class Person:
    ...:     def __init__(self, gender, age):
    ...:         self.gender = gender
    ...:         self.age = age
    ...:     def __repr__(self):
    ...:         return '{self.__class__.__name__}: <{self.gender}, {self.age>'.format(self=self)
    ...:
    ...:

In [12]: person = Person('male', 28)

In [13]: person
Out[13]: Person: <male, 28>

In [16]: print(person)
Person: <male, 28>


# 只实现__repr__和__str__
In [17]: class Person:
    ...:     def __init__(self, gender, age):
    ...:         self.gender = gender
    ...:         self.age = age
    ...:     def __repr__(self):
    ...:         return '__repr__ {self.__class__.__name__}: <{self.gender},{self.age>'.format(self=self)
    ...:     def __str__(self):
    ...:         return '__str__ {self.__class__.__name__}: <{self.gender}, {self.age>'.format(self=self)
    ...:

In [18]: person = Person('male', 28)

In [19]: person
Out[19]: __repr__ Person: <male, 28>

In [20]: print(person)
__str__ Person: <male, 28>

综上,__repr__返回的字符串应该准确、无歧义,方便我们调试和记录日志等__repr____str__ 的区别在于,后者一般是在str()函数被使用,或是在用print函数打印一个对象的时候才被调用的,并且它返回的字符串对终端用户更友好。如果你只想实现这两个特殊方法中的一个,__repr__ 是更好的选择,因为如果一个对象没有__str__函数,而Python又需要调用它的时候,解释器会用__repr__作为替代