1. 程式人生 > >流程python學習筆記:第一章

流程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__的作用是類似的