在 Python 中要将某一类型的变量或者常量转换为字符串对象通常有两种方法,即str() 或者 repr() 。
>>> a = 10
>>> type(str(a))
>>> type(repr(a))
但是这二者之间有什么区别呢?因为提供两个功能完全相同的内建函数是没有意义的。
区别
Python中的str( )和repr( )两个函数的区别,都是可以将任意的值转化为字符串:函数str( )将其转化成为适于人阅读的前端样式文本,而repr(object)就是原本未处理的用于编译器阅读的后台底层代码,下面直接上例子来说明这两个函数的用法。
对于字符串: a = ‘hello, world!\n’
>>> a
'hello, world!\n' #输出的a本来的模样
>>> print(a) #对a经过编译后的样式文本输出,将转义字符进行转义
hello,world!
>>> print(str(a)) #可以看到对str返回的值进行print处理,这将与直接print(a)得到相同的结果
hello,world!
>>> repr(a) #获得的是a原始输入的存在于存储器中用于机器底层编译的代码
"'hello, world!\n'"
>>> print(repr(a)) #对于repr返回的值进行print处理,可以看到这与直接在终端输入a,得到的是相同的结果 'hello,world!\n'
造成这两种输出形式不同的原因在于,print 语句结合 str() 函数实际上是调用了对象的 __str__
方法来输出结果。而 print 结合 repr() 实际上是调用对象的__repr__
方法输出结果,来实际对比一下看看。
>>> print(str('123'))
123
>>> print(str(123))
123
>>> print(repr('123'))
'123'
>>> print(repr(123))
123
不难发现,当我们把一个字符串传给str()函数再打印到终端的时候,输出的字符不带引号。而将一个字符串传给repr()函数再打印到终端的时候,输出的字符带有引号。
下例中我们用 str 对象直接调用这两个方法,输出结果的形式与前一个例子保持一致。
>>> print('123'.__repr__())
'123'
>>> print('123'.__str__())
123
这个例子可能还是无法很好表达到底 str() 与 repr() 各有什么意义,再看下一个例子
>>> from datetime import datetime
>>> now = datetime.now()
>>> print(str(now))
2017-04-22 15:41:33.012917
>>> print(repr(now))
datetime.datetime(2017, 4, 22, 15, 41, 33, 12917)
通过str()的输出结果我们能很好地知道 now 实例的内容,但是却丢失了 now 实例的数据类型信息。而通过repr()的输出结果我们不仅能获得 now 实例的内容,还能知道 now 是datetime.datetime
对象的实例。
因此 str() 与 repr() 的不同在于:
另外如果想要自定义类的实例能够被 str()和 repr()所调用,那么就需要在自定义类中重构__str__
和 __repr__
方法。
重构
在类中的使用,可以定义一些在实例运行时,控制repr()函数作用在其实例上时的行为。
class test(object):
def __init__(self, data):
self.data = data
仅仅是这样的话我们进行如下操作:
>>> t = test(100)
>>> t
<__main__.test at 0x4db85f8>
>>> print(t)
<__main__.test at 0x4db85f8>
>>> str(t)
'<__main__.test at 0x4db85f8>'
>>> repr(t)
'<__main__.test at 0x4db85f8>'
在类中没有方法的时候,如果直接在终端输入类的实例,不会输出任何东西的,上面显示的内容是由于类的特殊方法(基本定制型)有str()和repr(), 在print(object)和直接运行实例的时候回打印字符串。如果没有实现(覆盖)该函数,就会出现上面的结果。
那我们定义一个str函数来看看效果:
class test(object):
def __init__(self, data):
self.data = data
def __str__(self):
return "ss"
>>> t = test(100)
>>> t
<__main__.test at 0x4db85f8>
>>> str(t)
'ss'
>>>print(t)
ss
>>>repr(t)
<__main__.test at 0x4db85f8>
可以看到在这里直接输入t还会跟上面的例子的结果一致,但是str(t)和print(t)已经发生了改变,不难看出显示的是我们在类中定义的str()函数的返回值,而rerp(t)还是 跟上个例子一样,下面我们也来实现一个str()函数来看一看效果。
class test(object):
def __init__(self, data):
self.data = data
def __str__(self):
return "ss"
def __repr__(self):
return "gg"
>>> t = test(100)
>>> t
gg
>>> str(t)
'ss'
>>>print(t)
ss
>>>repr(t)
'gg'
>>> print(repr(t))
gg
如此可以很清楚的明白,默认的str() repr()函数与重构后的区别,以及这两者与直接输入和经过print处理以后的关系,也就是直接在终端输入对象,相当于调用print(repr(oblect))函数,如果没有被复写则会出现上面最开始的那种显示形式;而print(object)函数相当于调用了print(str(object))这个函数,如果没有被复写就是使用的默认的,也会出现上面的显示结果。
下面还有一个对于repr( )函数的说明:
Python中这个repr函数,对应repr(object)这个函数,返回一个可以用来表示对象的可打印字符串:
Python中,有的操作符和函数是做同样的事情,原因是某些场合下函数会比操作符更适合使用,比如函数对象可作为参数传递。