python中与0xf2相等的是_python中__str__与__repr__
(1)背景
python中,對(duì)于類(自定義類)的實(shí)例對(duì)象的默認(rèn)顯示既沒(méi)有太大用處,也不美觀。比如:
1 classadder:2 def __init__(self,value=0):3 self.data=value #初始化數(shù)據(jù)
4 def __add__(self,other):5 self.data+=other6>>> x=adder()7>>>print(x)
<__main__.adder. object at>8>>>x
而通過(guò)__str__或者_(dá)_repr__,可以定制化(costomise)顯示,比如,下面代碼中,在子類中定義了一個(gè)返回實(shí)例字符的__repr__方法。注意,在python3中所有對(duì)象都繼承了object的__str__,也就是實(shí)例對(duì)象的默認(rèn)顯示。
1 >>>classaddrepr(adder):2 def __repr__(self):3 return 'addrepr(%s)'%self.data4 >>>x=addrepr(2) #運(yùn)行__init__
5 >>>x+1 #運(yùn)行__add__
6 >>>x #運(yùn)行__repr__
7 addrepr(3)8 >>>print(x) #運(yùn)行__repr__
9 addrepr(3)10 >>>str(x),repr(x) #均運(yùn)行__repr__
11 ('addrepr(3)','addrepr(3)')
View Code
當(dāng)類實(shí)例化對(duì)象被打印或者轉(zhuǎn)化為字符時(shí),如果定義了__repr__(或者_(dá)_str__),那么該__repr__(或者_(dá)_str__)將被自動(dòng)調(diào)用,這里__repr__用了最基本的字符格式來(lái)將self.data轉(zhuǎn)化為友好的字符顯示。
(2)為什么要用兩種顯示方法
雖然__str__與__rer__的作用都是為了獲得更友好的字符顯示,但對(duì)于代碼的設(shè)計(jì)有一些細(xì)微的區(qū)別。
(a)對(duì)于print和str內(nèi)建函數(shù),程序會(huì)首先嘗試__str__函數(shù),如果沒(méi)有__str__函數(shù),則嘗試__repr__函數(shù),如果沒(méi)有__repr__函數(shù),則選用默認(rèn)顯示;
(b)在其他情況下,比如交互式回應(yīng)(interactive echoes),repr函數(shù),和嵌套中,__repr__被調(diào)用,一般地,它應(yīng)該為開(kāi)發(fā)者返回較為詳細(xì)的顯示。
下面通過(guò)代碼說(shuō)明兩種方法的不同:
1 >>>classaddstr(adder):2 def __str__(self):3 return '[value:%s]'%self.data4 >>>x=addstr(3)5 >>>x #默認(rèn)顯示6 <__main__.addstr object at>
7 >>>print(x) #調(diào)用__str__8 [value:4]9 >>>str(x),repr(x)10 ('[value:4]','<__main__.addstr object at>
(c)如果同時(shí)定義了兩種方法,那么可以在不同情況下,支持不同的顯示。如下面代碼:
1 >>>classaddboth(adder):2 def __str__(self):3 return '[value:%s]'%self.data4 def __repr__(self):5 return 'addboth(%s)'%self.dat6 >>>x=addboth(4)7 >>>x+1
8 >>>x #調(diào)用__repr__
9 addboth(5)10 >>>print(x) #調(diào)用__str__
11 [value:5]12 >>>str(x),repr(x) #分別調(diào)用__str_,__repr__
13 ('[value:5]','addboth(5)')
總結(jié)下來(lái)以上幾點(diǎn)就是:只有在print(),str()時(shí),才會(huì)調(diào)用__str__()(如果沒(méi)有__str__則調(diào)用__repr__),其他情況均調(diào)用__repr__,如交互式情況下單獨(dú)顯示,repr()等。
(3)使用的三點(diǎn)注意
(a)首先是__str__和__repr__必須均返回字符,返回其他類型,將會(huì)報(bào)錯(cuò),所以必要的話必須確保它們進(jìn)行字符轉(zhuǎn)換(比如str,%s)。
(b)根據(jù)容器(container)的字符轉(zhuǎn)換,僅有當(dāng)對(duì)象出現(xiàn)在print的頂層時(shí),才會(huì)調(diào)用__str__;嵌套在大的對(duì)象里的對(duì)象顯示,將仍調(diào)用__repr__,下面代碼說(shuō)明了這一點(diǎn):
1 >>>classPrinter:2 def __init__(self,value):3 self.value=value4 def __str__(self):5 returnstr(self.value)6 >>>objs=[Printer(2),Printer(3)]7 >>>for x in objs:print(x)8
9 2
10 3
11 >>>print(objs)12 [<__main__.printer object at>]13 >>>objs14 [<__main__.printer object at>,<__main__.printer object at>]
為確保不論有無(wú)容器,在所有情況下顯示設(shè)定的顯示模式,用__repr__,不用__str__,用如下代碼進(jìn)行說(shuō)明:
1 >>> classPrinter:2 def __init__(self,value):3 self.val=value4 def __repr__(self): #如果沒(méi)有__str__,調(diào)用__repr__
5 return '%s'%self.val6
7
8 >>> objs=[Printer(2),Printer(3)]9 >>> for x in objs:print(x)10
11 2
12 3
13 >>> print(objs) #調(diào)用__repr__
14 [2, 3]15 >>>objs16 [2, 3]
(c)第三,也是最為微妙的,顯示方法在極少情況下有時(shí)又也有可能觸發(fā)無(wú)限迭代循環(huán)(infinite recursion loops),因?yàn)橐恍?duì)象的顯示包括了其他對(duì)象的的顯示,而一個(gè)顯示觸發(fā)了正在被顯示的對(duì)象的顯示,因而進(jìn)入無(wú)限循環(huán)中。如下代碼:
"""this scripts is intended to illustrate the infinite recursion loops
caused by __repr__ overloading methods. displaying the value of a method,line10 in this script, can trigger the __repr__
of the class method, then the __repr__ method is called again, and the infinite recursion loops happen."""
classBase:def __init__(self):
self.data=1
defprint0(self):pass
defprint1(self):
a=str(getattr(self,'print0')) #Caution! getattr(object,attrname),attrname shall be string.
returnaclassNormal(Base):def __str__(self):return '%s'%self.print1()classRecursion(Base):def __repr__(self):return '%s'%self.print1()if __name__=='__main__':
a=Normal()
b=Recursion()print(a)try:print(b)exceptRecursionError:print('A recusion error happens')
運(yùn)行結(jié)果為:
>A recusion error happens
總結(jié)
以上是生活随笔為你收集整理的python中与0xf2相等的是_python中__str__与__repr__的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 无人陪伴儿童没有邮箱怎么填?
- 下一篇: websocket python爬虫_p