流暢的python python資料模型

2022-08-15 07:48:17 字數 4030 閱讀 8641

python最好的品質之一就是一致性。初步接觸python可能會len(collection)而不是collection.len()覺得不適應,這是通常所說的「python風格」(pythonic)的關鍵,體現在python的資料模型上,資料模型是對python框架的描述,它規範了這門語言自身構建模組的介面,這些模組包括但不限於序列、迭代器、函式、類和上下文管理器。

特殊方法:以兩個下劃線開頭,兩個下劃線結尾(例如__getitem__)。比如obj[key]背後就是__getitem__方法,為了能求得my_collection[key]的值,直譯器實際上會呼叫my_collection.__getitem__(key)。

import

collections

card = collections.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]

collections.namedtuple構建了乙個簡單的類表示一張紙盤,用以構建只有少數屬性但是沒有方法的物件,比如資料庫條目。

>>> beer_card = card('

7', '

diamods')

>>>beer_card

card(rank='

7', suit='

diamods

')

用len()函式看看一疊牌有多少張:

>>> deck =frenchdeck()

>>>len(deck)

52

從一疊牌中抽取特定的一張,比如第一張或者是最後一張,以下這些都是由__getitem__方法提供的:

>>>deck[0]

card(rank='

2', suit='

spades')

>>> deck[-1]

card(rank='

a', suit='

hearts')

>>>

也可以隨機抽取一張紙牌

>>> from random import

choice

>>>choice(deck)

card(rank='

4', suit='

clubs')

>>>choice(deck)

card(rank='

8', suit='

clubs')

>>>choice(deck)

card(rank='

10', suit='

diamonds

')

這是因為__getitem__方法把操作交給了self._cards列表,所以deck類會自動支援切片操作。

>>> deck[:3]

[card(rank='

2', suit='

spades

'), card(rank='

3', suit='

spades

'), card(rank='

4', suit='

spades')]

>>> deck[12::13]

[card(rank='

a', suit='

spades

'), card(rank='

a', suit='

diamonds

'), card(rank='

a', suit='

clubs

'), card(rank='

a', suit='

hearts

')]

另外僅僅實現了__getitem__方法,這一摞牌就變成可迭代了

>>> for card in

deck:

...

print

(card)

...

card(rank='

2', suit='

spades')

card(rank='

3', suit='

spades')

...

in運算子會按照順序做迭代搜尋,

>>> card('

q', '

hearts

') in

deck

true

>>> card('

7', '

beasts

') in

deck

false

排序,按照黑桃最大、紅桃次之、方塊再次、梅花最小

>>> suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)

>>> def

spades_high(card):

... rank_value =frenchdeck.ranks.index(card.rank)

...

return rank_value * len(suit_values) +suit_values[card.suit]

...

>>> for card in sorted(deck, key=spades_high):

...

print

(card)

...

card(rank='

2', suit='

clubs')

card(rank='

2', suit='

diamonds')

card(rank='

2', suit='

hearts

')

按照目前的設計,frenchdeck是不能洗牌的。

如何使用特殊方法

特殊方法的存在是為了被python直譯器呼叫的,是隱式的,並不需要呼叫他們。也就是說沒有my_object.__len__()這種寫法,而應該是len(my_object)。如果是python內建的型別,比如列表list、字串str,等,那麼__len__會直接返回ob_size屬性。

比如for i in x:這個語句,背後用的是iter(x),而這個函式的背後則是x.__iter__()方法。

通常**無需直接使用特殊方法,除了__init__方法。

通過內建的函式(例如len、iter、str等等)來使用特殊方法是最好的選擇,他們的速度更快。

另外不要自己想當然地隨意新增特殊方法,比如__foo__之類的,因為雖然現在這個名字沒有被python內部使用,以後就不一定了。

字串表達形式

python有乙個內建的函式是repr,它能把乙個物件用字串的形式表達出來以便辨認。

%和str.format這兩種格式化字串的方法目前都在使用,但是str.format可能會越來越適用。

__repr__和__str__的區別在於,後者是在str()函式被使用,或者是在print函式列印才被呼叫的,並且返回的字串對終端使用者更友好。如果只想實現這兩種中的一種,那麼__repr__會是更好的選擇。

流暢的python 《流暢的python》第一天

我們看到 python 可以用len 或者arr 0 它們是怎麼實現的,其實就是兩個魔法方法 len 和 getitem 用撲克牌的例子學習一下,我們知道知道撲克牌有花色 黑桃,紅桃,方塊,梅花 有大小 2 10 jqka 如何創造一套牌的物件呢?首先學習collections的namedtuple...

ssh的執行流暢

ssh執行流程 2.客戶瀏覽器傳送請求,請求到達struts2的核心控制器,如果是action請求,struts2控制器根據struts.xml的配置,要呼叫乙個指定的action物件的具體方法來處理.3 action中處理方法,呼叫service業務層方法來處理,業務層的處理方法,呼叫dao層資料...

python python的方法覆蓋

之前一直以為在python裡是不能使用方法覆蓋的,結果後來發現可以,這裡寫乙個簡單的例子。class a def test self print i m a class b a def test self print i m b a a b b a.test b.test 列印輸出和預想的一樣,輸出...