第一章数据模型
1.Python风格的纸牌
- 从一叠牌中抽取特定的一张纸牌,比如说第一张或最后一张,是很容易
的:deck[0] 或 deck[-1]。这都是由 getitem 方法提供的
- 随机选出一张牌: 使用random.choice
- 总结:使用特殊方法的好处:
作为你的类的用户,他们不必去记住标准操作的各式名称(“怎么得到元素的总数?是 .size() 还是 .length() 还是别的什么?”)。更加方便的利用python标准库, 比如random.choice函数,从而不必重复发明轮子
2.模拟数值类型
跟运算符无关的特殊方法
类别 | 方法名 |
字符串/字节序列表示形式 |
repr,str,format,bytes |
数值转换 | abs,bool,complex,int,float,hash,index |
集合模拟 | len,getitem,setitem,delitem,contains |
迭代枚举 | iter,reversed,next |
可调用模拟 | call |
上下文管理 | enter, exit |
实例创建和销毁 | new,init,del |
属性管理 | getattr, getattribute, setattr, delattr, dir |
属性描述符 | get, set, delete |
跟类相关的服务 | prepare, instancecheck, subclasscheck |
跟运算符相关的特殊方法
一元运算符 | _neg_- _pos_+ _abs_ abs() |
众多比较运算符 | _lt_< _le_<= _eq_== _ne_!= _gt_> _ge_>= |
算术运算符 | _add_+ _sub_- _mul_* _truediv_/ _floordiv_// _mod_% _divmod_divmod() _pow_**或pow() _round_ round() |
反向算术运算符 | _radd_ _rsub_ _rmul_ _rtruediv_ _rfloordiv_ _rmod_ _rdivmod_ _rpow_ |
增量赋值算术运算符 | _iadd_ _isub_ _imul_ _itruediv_ _ifloordiv_ _imod_ _ipow_ |
位运算符 | _invert_~ _lshift_<< _rshift_>> _and_& _or_| _xor_^ |
反向位运算符 | _rlshift_ _rrshift_ _rand_ _rxor_ _ror_ |
增量赋值位运算符 | _ilshift_ _irshift_ _iand_ _ixor_ _ior_ |
from random import choice
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]
beer_card = Card('7', 'diamonds')
print(beer_card)
deck = FrenchDeck()
print(len(deck))# len()的使用是使用 __len__ 函数
print((deck[0]))
# 抽取特定序号的元素,如最后一个deck[-1],由__getitem__提供
print((deck[-1]))
# 使用Python内置的随机函数random.choice() 获取一张随机牌
print(choice(deck))
print(choice(deck))
print(choice(deck))
print('---------------------------------------')
print((deck._cards[:3]))
print((deck._cards[12::13]))
#可迭代
for card in deck:
print(card)
print('++++++++++++++++++++++++')
# 反向迭代
for card in reversed(deck):
print(card)
print('>>>>>>>>>>>>>>>>>>>>>>>>>>>')
# 使用Python内置的随机函数random.choice() 获取一张随机牌
# in 运算符
print(Card('Q', 'hearts') in deck)
print(Card('7', 'beasts') in deck)
# 排序:先看点数,再比较花色
# 点数:2最小,A最大; 花色:黑桃>红桃>方块>梅花 --> 梅花2最小,为0,黑桃A最大,为52
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)