主要知识:
1,__len__是被解释器调用的,使用时只需len(obj)
2,__repr__得到对象的字符串表现形式
3,if obj,实际执行的是bool(obj),python解释器调用obj.__bool__,如果没有__bool__,会调用__len__看是否为0
4,len(obj),python解释器调用obj.__len__()
5,obj[key],python解释器调用obj.__getitem__(key)
6,除了__init__,通常不需要写特殊方法
eg1,python风格的纸牌
import collections import random Card = collections.namedtuple('Card', ['rank', 'suit']) # 定义了Card类,包含'rank'和'suit'属性 class FrenchDeck(object): 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] suit_values = {'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] print(Card('7', 'diamond')) # Card(rank='7', suit='diamond') deck = FrenchDeck() print(len(deck)) # 52,调用了__len__ print(deck[0]) # Card(rank='2', suit='spades'), 调用了__getitem__ print(deck[-1]) # Card(rank='A', suit='hearts') print(random.choice(deck)) # 随机抽一张卡牌 print(deck[:3]) # 上面3张:[Card(rank='2', suit='spades'), Card(rank='3', suit='spades'), Card(rank='4', suit='spades')] print(deck[12::13]) # 打印4张A,第13张,然后每隔步长13打印 for card in deck: print(card) # 打印所有卡牌 for card in reversed(deck): print(card) # 反向打印所有卡牌 for card in sorted(deck, key=spades_high): # 按suit_values指定的花色判断进行排序 print(card)
eg2,一个简单的二维向量
from math import hypot class Vector(object): def __init__(self, x=0, y=0): self.x = x self.y = y def __repr__(self): return 'Vector(%r, %r)'%(self.x, self.y) # 应该要打印返回字符串,r改成s也行 def __abs__(self): return hypot(self.x, self.y) # hypot返回 sqrt(x*x + y*y),sqrt开根号 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) v1 = Vector(2, 4) v2 = Vector(3, 4) print(v1) # Vector(2, 4)