Python str VS repr
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__
作为替代。