
- 一、主要知识点:
- 1. collections.namedtuple
- 2. 魔法(特殊)方法在自定义类中的实现
- 二、代码部分
- 1. 一摞有序的纸牌
- 2. 一个简单的二维向量类
- Reference
- __getitem__ 妙用
- __repr__ 和 __str__ 的区别
# 1.1 一摞有序的纸牌
import collections
from random import choice
Card = collections.namedtuple("Card", ["rank", "suit"])
suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)
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 rank in self.ranks for suit in self.suits]
def __len__(self):
return len(self._cards)
# __getitem__ in builtins: return self[key]
# 通过实现 __getitem__ 方法,可以将对象变成可迭代对象
def __getitem__(self, position):
return self._cards[position]
def spades_high(card):
rank_value = FrenchDeck.ranks.index(card.rank)
return rank_value * len(suit_values) + suit_values[card.suit]
deck = FrenchDeck()
for card in sorted(deck, key=spades_high, reverse=True):
print(card)
2. 一个简单的二维向量类
# 特殊方法的存在是为了被 Python 解释器调用的,自己并不需要调用它们。
# 没有 my_object.__len__() 这种写法,而应该使用 len(my_project)。
# 在执行 len(my_object) 的时候,若该对象是一个自定义类的对象,Python 会自己去调用其中由你自己实现的 __len__ 方法。
# 除非有大量的元编程存在,通常代码无需直接使用特殊方法,直接调用特殊方法的频率应该远远低于实现它们的次数。(不要随意添加特殊方法)
# 1.2.1 一个简单的二维向量类
from math import hypot
class Vector:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
# __repr__: 字符串表示形式,如果没有实现 __repr__,打印一个向量的实例可能会显示
# __repr__ 返回的字符串应当准确、无歧义,且尽可能表达出如何用代码创建出这个被打印的对象,e.g. Vector(3, 5)
# __repr__ vs __str__:
# 1. 前者表述更明确清晰,方便调试和记录日志;
# 2. 后者返回的字符串易读,对终端用户更友好,适合输出给用户
# 3. 如果只能取其一,推荐选择 __repr__
def __repr__(self):
return "Vector(%r, %r)" % (self.x, self.y) # %r 获取对象各个属性的标准字符串表示形式
def __abs__(self):
return hypot(self.x, self.y)
# 对于判定一个值 x 为真还是为假,Python 会调用 bool(x),该函数将返回 True or False
# bool(x) 背后调用的是 x.__bool__() 的结果,若不存在 __bool__ 方法,则 bool(x) 尝试调用 x.__len__()
# 默认情况下,自定义类的实例总被认为是真的,除非对 __bool__ 或 __len__ 有自己的实现
def __bool__(self):
return bool(abs(self)) # 在此,通过判断向量的模是否为 0 来判断 Vector 的布尔值
# return bool(self.x or self.y) # more efficient realization while not straightforward
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)
Reference
[1] Ramalho L. Fluent Python: Clear, concise, and effective programming[M]. " O’Reilly Media, Inc.", 2015.
[2] Fluent Python (2nd Edition)
[3] Fluent Python 2e example code
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)