2012年4月28日 星期六

python 的特殊方法名稱


class Rational:
def __init__(self, n, d): # 物件建立之後所要建立的初始化動作
self.numer = n
self.denom = d

def __str__(self): # 定義物件的字串描述
return str(self.numer) + '/' + str(self.denom)

def __add__(self, that): # 定義 + 運算
return Rational(self.numer * that.denom + that.numer * self.denom,
self.denom * that.denom)

def __sub__(self, that): # 定義 - 運算
return Rational(self.numer * that.denom - that.numer * self.denom,
self.denom * that.denom)

def __mul__(self, that): # 定義 * 運算
return Rational(self.numer * that.numer,
self.denom * that.denom)

def __truediv__(self, that): # 定義 / 運算
return Rational(self.numer * that.denom,
self.denom * that.denom)

def __eq__(self, that): # 定義 == 運算
return self.numer * that.denom == that.numer * self.denom

x = Rational(1, 2)
y = Rational(2, 3)
z = Rational(2, 3)
print(x) # 1/2
print(y) # 2/3
print(x + y) # 7/6
print(x - y) # -1/6
print(x * y) # 2/6
print(x / y) # 3/6
print(x == y) # False
print(y == z) # True

__str__()用來定義傳回物件描述字串,通常用來描述的字串是對使用者友善的說明文字,如果對物件使用str(),所呼叫的就是__str__()。如果要定義對開發人員較有意義的描述,例如傳回產生實例的類別名稱之類的,則可以定義__repr__(),如果對物件使用repr(),則所呼叫的就是__repr__()。

在 特性名稱空間 中看過的例子則是

__getattr__():而用來定義實例的特性被取得時該作什麼動作
__setattr__():而用來定義實例的特性被設定時該作什麼動作。例如:





__getitem__()與__setitem__()則用來設定 []運算子 的行為。例如:




>>> class Some:
...     def __init__(self):
...         self.inner = {}
...     def __setitem__(self, name, value):
...         self.inner[name] = value
...     def __getitem__(self, name):
...         return self.inner[name]

在Python中,你可以讓物件實作__iter__()方法,這個方法可以傳回一個迭代器(Iterator),一個具有__next__()方法的物件。迭代器走訪物件內容收集物件後傳回,每次呼叫迭代器物件的__next__()方法,必須傳回群集的下一個元素,如果沒有下一個元素了,則丟出StopIteration物件。例如:
class Some:
class Iterator:
def __init__(self, length):
self.length = length
self.number = -1
def __next__(self):
self.number = self.number + 1
if self.number == self.length:
raise StopIteration
return self.number

def __init__(self, length):
self.length = length

def __iter__(self):
return Some.Iterator(self.length)

s = Some(3)
it =
iter(s)
print(
next(it)) # 0
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # StopIteration
實際上,你可以使用iter()來代為呼叫物件的__iter__()方法,使用next()方法代為呼叫物件的__next__()方法。事實上,你可以結合for in迴圈來提取物件,for in迴圈會透過__iter__()取得迭代器,然後在每次迴圈中呼叫__next__()方法,而後遇到StopIteration丟出後離開迴圈。例如:
for n in Some(10):    print(n)       # 顯示 0 到 9
以上先簡介一些簡單的特殊方法名稱,詳細的特殊方法說明,可以參考 Special method names
另外還有描述器(descriptor) def __get__(self, instance, owner)def __set__(self, instance, value)def __delete__(self, instance)詳細的使用方法請參考 python描述器 一文
在Python中,所謂描述器,是用來描述特性的取得、設定、刪除該如何處理的物件,也就是說,當描述器實際是某個類別的特性成員時,對於類別特性的取得、設定或刪除,將會交由描述器來決定如何處理(除了那些內建特性,如__class__等特性之外)。例如:
class Descriptor:
def __get__(self, instance, owner):
print(self, instance, owner)
def __set__(self, instance, value):
print(self, instance, value)
def __delete__(self, instance):
print(self, instance)

class Some:
x = Descriptor()

沒有留言:

張貼留言