1、打印操作會首先嘗試__str__和str內置函數,他通常返回一個用戶友好顯示。__repr__用于所有其他環境,用于交互式模式下提示回應以及repr函數,如果沒有使用__str__,則會使用print和str。它通常返回一個編碼字符串,可以用來重新創建對象,或則給開發者一個詳細的顯示。總而言之,除了當定義一個__str__的時候,使用print和str。然而需要注意,如果沒有定義__str__,打印還是使用__repr__,反過來不成立。在交互模式下,只適用__repr__,并且根本不嘗試__str__.
2、__str__,__repr__都必須返回字符串,返回其他類型會抱錯。還有一個需要注意的是,__str__的用戶友好顯示可能只有對象出現在一個打印操作的頂層時候才應用,嵌套 到較大對象中 的對象 可能用其__repr__或默認方法打印。
例如:
class Printer:
def __init__(self,val):
self.val = val
def __str__(self):
return str(self.val)
obj = [Printer(2),Printer(3)]
for x in obj:
print(x) #輸出:2 3
print(obj) #輸出:[<__main__.printer object at>, <__main__.printer object at>]
但是__repr__能夠解決前面提的那個問題
class Printer:
def __init__(self,val):
self.val = val
def __repr__(self):
return str(self.val)
obj = [Printer(2),Printer(3)]
for x in obj:
print(x) #輸出:2 3
print(obj) #輸出:2,3
3、右側加法和原處加法:__radd__,__iadd__
class adder:
def __init__(self,value=0):
self.data = value
def __add__(self,,other):
self.data+=other
adder只是在+左邊是對象時使用,如果要支持右側使用實例對象,則需要重載 __radd__.
例如:
class Commuter:
def __init__(self,val):
self.val = val
def __add__(self,other):
print('add',self.val,other)
return self.val+other
def __radd__(self,other):
print('radd',self.val,other)
return other+self.val #這個 順序無所謂,只是在調用的時候很位置很重要
x = Commuter(88)
y = Commuter(99)
print(x+1)
print('#'*8)
print(1+y)
print('$'*8)
print(x+y)
#輸出結果如下:
add 88 1
89
########
radd 99 1
100
$$$$$$$$
add 88 <__main__.commuter object at>
radd 99 88
187
原處加法: __iadd__或者__add__但是__iadd__更高效
class Number:
def __init__(self,val):
self.val = val
def __iadd__(self,other):
self.val+=other
return self
x = Number(5)
x+=1
x+=1
print(x.val) #輸出:7
或者
class Number:
def __init__(self,val):
self.val = val
def __add__(self,other):
return Number(self.val+other)
4、call表達式:__call__
有關python的__call__在官方文檔上有這么一句解釋 (http://docs.python.org/reference/datamodel.html?highlight=__call__#object.__call__)
object.__call__(self[, args...])
Called when the instance is “called” as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...).
當把一個實例當作方法來調用的時候,形如instance(arg1,args2,...),那么實際上調用的就是 instance.__call__(arg1,arg2,...)
例如:
class Prod:
def __init__(self,value):
self.value = value
def __call__(self,other):
return self.value *other
x = Prod(2)
print(x(3)) #輸出:6
5、比較:__lt__,__gt__和其他方法
比較運算沒有位置限制。
比較運算沒有隱士關系,比如說 == 為真并不以為著 !=為假
python2.6中如果沒有定義更為具體的比較方法,對其使用一個__cmp__或者內置cmp函數。
cmp( x, y)
Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.
class C:
def __init__(self,data):
self.data = data
def __gt__(self,other):
return self.data > other
def __lt__(self,other):
return self.data < other
x = C('spam')
print('1',x >'ham')
print('2','ham'> x)
print('3',x < 'ham')
print('4','ham'
y = C('ham')
print('5',x
print('6',x>y)
6、布爾測試:__bool__,__len__
在布爾環境中,python首先嘗試__bool__來獲取一個直接布爾值,然后如果沒有該方法,就嘗試__len__類根據對象的長度確定 一個真值。
7、對象析構函數:__del__
每當實例產生時,就會調用__init__構造函數,每當 實例空間被回收時,就會執行析構函數。
class Life:
def __init__(self,name='unknow'):
print('hello ',name)
self.name = name
def __del__(self):
print('Goodbye',self.name)
brain = Life('Brain')#輸出 hello brain
brain = 'loretta' #輸出: Goodbye brain