Python提供了一个完善的数据模型,只有符合这个数据模型才可以更方便地进行开发,才能尽可能地提升开发效率。下面就来演示两个简单的功能,Python Data Model 为自定义的数据类型(通过 Class)提供与 Python 内建类型一致的接口。实现方法是:在类中定义一些特殊的方法,比如 __add__() ;当开发者调用 len(object) 时,python 解析器将执行 object.__len__()。当调用deck[0]时,就是执行object.__getitem__()。就这两简单的函数重载,就已经可以全部使用python对象模型的大部分操作,获得了强劲的功能。演示的代码如下:
import collections
from random import choice
Card = collections.namedtuple('Card', ['rank', 'suit'])
class FrenchDeck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = '黑桃 菱形 梅花 心形'.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]
c1 = Card('7', '菱形')
print(c1)
d = FrenchDeck()
print('len(d)={}'.format(len(d)))
print('d[0]={},{}'.format(d[0], d[-1]))
print('d={},{}'.format(choice(d), choice(d)))
print('d[:4]={}'.format(d[:4]))
for i in d:
print('{}'.format(i))
for i in reversed(d):
print('{}'.format(i))
print(c1 in d)
suit_values = {'黑桃':3, '心形':2, '菱形':1, '梅花':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(d, key=spades_high):
print(card)
由上面代码可知,python为什么这么强大和高效,就是因为它已经提供大量的内置的功能特性,不需要用户再去构造。只需要一个__getitem__()函数的实现,就可以提供完善的支持。具体用到的功能:
d = FrenchDeck()
print('len(d)={}'.format(len(d)))
这里实现元素个数计算,也回答了为什么计算对象的长度不是使用对象的方法,而是使用函数len()来实现,因为len()函数是使用c代码实现,同时它是计算对象的内存大小来完成的,在python对象内无法进行计算。
print('d[0]={},{}'.format(d[0], d[-1]))
这里实现随机访问元素。
print('d={},{}'.format(choice(d), choice(d)))
这里实现函数式随机访问。
print('d[:4]={}'.format(d[:4]))
这里实现了切片式访问。
for i in d:
print('{}'.format(i))
for i in reversed(d):
print('{}'.format(i))
这里实现了迭代式访问。
print(c1 in d)
这里实现集合是否包含的测试。
suit_values = {'黑桃':3, '心形':2, '菱形':1, '梅花':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(d, key=spades_high):
print(card)
这里实现了排序函数访问对象。