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

2021-10-12 09:04:08 字數 3481 閱讀 5907

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

首先學習collectionsnamedtuple,這是乙個快速建立物件,有少數屬性但是沒有方法的,進一步學習可以查相關文件。這個非常適合作我們一張牌的物件。所以建立一套牌物件**如下:

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, item):

return self._cards[item]

上面是一套牌物件,有魔法方法__len____getitem__我們測試一下**

if __name__ == '__main__':

import random

deck = frenchdeck()

# 求長度

print("長度", len(deck))

# 索引

print("索引0", deck[0])

print("索引-1", deck[-1])

# 切片

print("切片", deck[1:4:2])

# 迭代

for card in deck:

print("迭代", card)

# 包含

print("包含", card("q", "hearts") in deck)

# 隨機選擇

print("隨機選擇", random.choice(deck))

# 排序 我們認為數字2最小 a最大 花色 黑桃》紅桃》方塊》梅花

def sort_help(card):

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

rank_val = deck.ranks.index(card.rank)

return rank_val * 4 + suit_values[card.suit]

for card in sorted(deck, key=sort_help):

print("排序", card)

我們可以把物件像陣列一樣操作,可以求長度,索引,迭代,包含,排序等。。。

我們用向量來舉例子,要實現一下需求

向量加法vector(2, 4) + vector(2, 1) = vector(4, 6)向量乘法vector(3, 4) * 3 = vector(9, 12)向量的模|vector(3, 4)| = 5

上面vector類的實現要用到__repr__, __abs__, __add__, __mul__**如下

from math import hypot

class vector:

def __init__(self, x: int = 0, y: int = 0):

self.x = x

self.y = y

def __repr__(self):

return "vector({}, {})".format(self.x, self.y)

# 求模

def __abs__(self) -> float:

return hypot(self.x, self.y)

# 求bool

def __bool__(self) -> bool:

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, other):

return vector(self.x * other, self.y * other)我們

我們測試**

if __name__ == '__main__':

x1 = vector(3, 4)

x2 = vector(6, 8)

# __repr__ 和 __str__ 的區別

# __str__ 只有 str 或者 print被使用

# 如果只想實現乙個 __repr__是更好的選擇,因為如果乙個物件

# 沒有 __str__ 函式,而 python 又需要呼叫它的時候,直譯器會用 __repr__ 作為替代。

print(x1)

# 求模

print(abs(x1))

# 加print(x1 + x2)

# 乘print(x1 * 3)

# bool

print(bool(x1))

附上特殊方法一覽表:

小結:我們自定義資料可以表現和內建型別一樣,通過魔法方法實現。

__repr__方便我們除錯和記錄日誌,__str__來給終端使用者看。

記錄學習 《流暢的python》第一天,一定要堅持下去!

流暢的python 魔術方法

第一章 流暢的python 裡面的描述 python 的魔術方法 magic method 是特殊方法的暱稱。一般是用 雙下劃線 名稱 雙下劃線 形式來表示,整體念起來也拗口,所以也有人把這種特殊方法名為稱為 雙下方法 dunder method 有關於特殊方法一覽,可以參考data model t...

流暢的python學習1

usr bin env python3 coding utf 8 created on mon apr 20 21 08 08 2020 author root import collections card collections.namedtuple card rank suit class f...

推薦書籍《流暢的Python》

我剛學程式設計的時候,有位從事c 開發的好友,傳授我經驗 工作中80 的時間用著那常用的20 的語言知識,其他的等你需要的時候再去看就好了設想在初學python 或者其他語言 的時候只是去學習那20 常用的,如果再不願意去精進,那麼可能我永遠都不會有機會去了解描述符,也不會使用元類,最後成了乙個以為...