流程python學習筆記:第一章
這一章中作者簡要的介紹了python資料模型,主要是python的一些特殊方法。比如__len__, __getitem__. 並用一個紙牌的程式來講解了這些方法
首先介紹下Tuple和nametuple的區別:
Nametuple是類似於元組的資料型別。除了能夠用索引來訪問資料,還支援用方便的屬性名來訪問資料。
傳統的元組訪問如下。對每個元素的訪問都必須通過索引來找到。這種找法很不直觀
tup1=('abc','def','ghi') print tup1[1]
使用nametuple來構造:
tup2=namedtuple('tuple2',['name','age','height']) t1=tup2('zhf','33','175') print t1 print t1.age print t1.height print t1.name
得到結果如下,namedtupel中tuple2是型別名,name,age,height是屬性名字
從上面的訪問可以看到,直接用t1.age的方法訪問更加直觀。當然也可以用索引比如t1[0]的方法來訪問
namedtupe1也支援迭代訪問:
for t in t1: print t
和元組一樣,namedtupel中的元素也是不可變更的。如果執行t1.age+=1。將會提示無法設定元素
Traceback (mostrecent call last):
File "E:/py_prj/fluent_py.py", line17, in <module>
t1.age+=1
AttributeError: can'tset attribute
下面來看下書中的紙牌例子,程式碼如下:
from collections import namedtuple Card=namedtuple('Card',['rank','suit']) class FrenchDeck: ranks=[str(n) for n in range(2,11)] + list('JQKA') suits='spades diamonds clubs hearts'.split() def __init__(self): self._cards=[Card(rank,suit) for suit in self.suits
for rank in self.ranks] def __len__(self): return len(self._cards) def __getitem__(self, position): return self._cards[position] if __name__=='__main__': deck=FrenchDeck() print len(deck) print deck[1]
首先定義了的紙牌元組Card, rank代表紙牌數字,suit代表紙牌花色。然後在FrenchDeck首先定義了ranks和suit的具體指。在__init__中對self._cards進行初始化。
__len__反饋self._cards的長度。__getitem__反饋具體的紙牌值。
結果如下,紙牌的長度為52,其中deck[1]為Card(rank=’3’,suit=’spades’)
可以看到len(deck)其實呼叫的是__len__方法。deck[1]呼叫的是__getitem__
由於有了__getitem__方法,還可以進行迭代訪問,如下:
for d in deck: print d
既然是可迭代的,那麼我們可以模擬隨機發牌的機制。
from random import choice
print choice(deck)
得到結果:
Card(rank='9',suit='hearts')
接下來看另外一個例子,關於向量運算的。比如有向量1vector1(1,2),向量2 vector2(3,4)。那麼vector1+vector2的結果應該是(4,6)。Vector1和vector2都是向量,如何實現運算呢。方法是__add__,__mul__
程式碼如下:
class vector: def __init__(self,x=0,y=0): self.x=x self.y=y def __repr__(self): return 'Vector(%r,%r)' % (self.x,self.y) def __abs__(self): return hypot(self.x,self.y) def __bool__(self): return bool(abs(self)) def __add__(self,other): x=self.x+other.x y=self.y+other.y return vector(x,y) def __mul__(self, scalar): return vector(self.x*scalar,self.y*scalar)
if __name__=='__main__': v1=vector(1,2) v2=vector(2,3) print v1+v2 print abs(v1) print v1*3
運算結果如下:
在這裡__add__,__mul__,__abs__分別實現了向量加法,乘法,以及求模的運算。
值得一提的是__repr__的方法。這個方法是在需要列印物件的時候呼叫。例如print vector(1,2)的時候得到vector(1,2). 否則就是表示物件的字串:<Vector object at 0x0000>.這個__repr__和__str__的作用是類似的