python最好的品質之一就是一致性。初步接觸python可能會len(collection)而不是collection.len()覺得不適應,這是通常所說的「python風格」(pythonic)的關鍵,體現在python的資料模型上,資料模型是對python框架的描述,它規範了這門語言自身構建模組的介面,這些模組包括但不限於序列、迭代器、函式、類和上下文管理器。
特殊方法:以兩個下劃線開頭,兩個下劃線結尾(例如__getitem__)。比如obj[key]背後就是__getitem__方法,為了能求得my_collection[key]的值,直譯器實際上會呼叫my_collection.__getitem__(key)。
importcollections
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 importchoice
>>>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 indeck:
...
(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):
...
(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 列印輸出和預想的一樣,輸出...