Python中的str()函数和repr()函数

在 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()所调用,那么就需要在自定义类中重构__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)这个函数,返回一个可以用来表示对象的可打印字符串:

  • 尝试生成这样一个字符串,将其传给 eval()可重新生成同样的对象 ;
  • 否则,生成用尖括号包住的字符串,包含类型名和额外的信息(比如地址) ;
  • 一个类(class)可以通过 repr() 成员来控制repr()函数作用在其实例上时的行为。

Python中,有的操作符和函数是做同样的事情,原因是某些场合下函数会比操作符更适合使用,比如函数对象可作为参数传递。

你可能感兴趣的:(Python)