流畅的python--python的数据模型

 

 如何使用特殊方法

import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])
'''
class Card{
    public string rank{get;set;}
    public string suit{get;set;}
}
'''

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split()
    
    '''
    _cards = List<Card>():
    Card.rank = ranks[0];
    Card.suit = suits[0];
    '''
    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits
                      for rank in self.ranks]

#python解释器在碰到特殊的句法时,会使用特殊方法去激活一些基本的对象操作,特殊方法表示为:以两个下划线开头,以两个下划线结尾,比如以下__len__()方法和__getitem__()方法
#特殊方法名作用:能让你自己的对象实现和支持以下的语言框架,并与之交互,迭代、集合类、属性访问、运算符重载、函数和方法的调用、对象的创建和销毁、字符串表示形式和格式化、管理上下文(即with块)
#如何使用特殊方法:特殊方法的存在是为了被python解释器调用的,自己并不需要调用它们,也就是没有my_object.__len__()这种写法,而应该使用len(my_object)
def __len__(self): return len(self._cards)

#比如obj[key]的背后就是__getitem__方法,为了能求得FrenchDeck[key]的值,解释器实际上会调用FrenchDeck.__getitem__(key)
def __getitem__(self, position): return self._cards[position] beer_card = Card(rank='7', suit='diamonds') print(beer_card) # >> Card(rank='7', suit='diamonds')
deck
= FrenchDeck() l = len(deck) #len方法是FrenchDeck类的特殊方法,实际调用的是deck.__len__(deck) print(l) # >>52
print(deck[0]) #实际调用的是 deck.__getitem__(0)方法
# >> Card(rank='2', suit='spades')
print(deck[-1]) #deck.getitem(12)
# >> Card(rank='A', suit='hearts')
from random import choice tempCard= choice(deck) #随机抽取一张牌print(deck[:3]) print(deck[12::13]) #从12开始,每隔13张牌取一张 deck[12] deck[12+13] ...... for card in deck: # 正向循环 print(card)
'''
>>输出
Card(rank='2', suit='spades')
Card(rank='3', suit='spades')
Card(rank='4', suit='spades')
Card(rank='5', suit='spades')
Card(rank='6', suit='spades')
......
'''
for card in reversed(deck): #反向循环 
print(card)
'''
>>输出
Card(rank='A', suit='hearts')
Card(rank='K', suit='hearts')
Card(rank='Q', suit='hearts')
Card(rank='J', suit='hearts')
Card(rank='10', suit='hearts')
......
'''
 
print(Card('Q', 'hearts') in deck)  #判断Card('Q', 'hearts')在不在deck里
# >> true
print(Card('B', 'hearts') in deck) #判断Card('B', 'hearts')在不在deck里 # >> false suit_values = dict(spades=3, hearts=2, diamond=1, clubs=0) def spades_high(card): rank_value = FrenchDeck.ranks.index(card.rank) #找到牌面数字的下标
#对于deck类,print(card.rank, rank_value)
#>> 输出
'''
2 0
3 1
4 2
......
'''
return rank_value * len(suit_values) + suit_values[card.suits] #得到每个元素的排序值
# 对于牌面值为2来说,2的下标为0,2有四种花色,rank_value * len(suit_values)得到了牌面值2的排序分数,suit_values[card.suits]代表每一种花色的排序数值分数,将两者相加,得到了牌面值2的整体排序分数
for card in sorted(deck, key=spades_high): print(card)
'''
>>输出
Card(rank='2', suit='clubs')
Card(rank='2', suit='diamonds')
Card(rank='2', suit='hearts')
Card(rank='2', suit='spades')
Card(rank='3', suit='clubs')
Card(rank='3', suit='diamonds')
Card(rank='3', suit='hearts')
......
'''
for card in sorted(deck, key=spades_high, reverse=True): #reverse参数表示正序倒序
    print(card)
'''
>>输出
Card(rank='A', suit='spades')
Card(rank='A', suit='hearts')
Card(rank='A', suit='diamonds')
Card(rank='A', suit='clubs')
Card(rank='K', suit='spades')
Card(rank='K', suit='hearts')
Card(rank='K', suit='diamonds')
......
'''

 

字符串表达形式

from math import hypot

class Vector:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    #内置函数,得到类对象的字符串表示形式
#python有一个内置的函数是repr,它能把一个对象用字符串的形式表达出来以便辨认
#%和str.format这两种格式化字符串的方法目前都在使用,但是str.format可能会越来越适用
#__repr__和__str__的区别在于,后者是在str()函数被使用,或者是在print函数打印才被调用的,并且返回的字符串对终端用户更友好。如果只想实现这两种中的一种,那么__repr__会是更好的选择,因为如果一个对象没有 __str__ 函数,
#而 Python 又需要调用它的时候, 解释器会用 __repr__ 作为替代
    def __repr__(self):
        return 'Vector(%r, %r)' %(self.x, self.y)
    def __abs__(self):
        return hypot(self.x, self.y)
    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)
print(v1)
# >> Vector(2, 4)
print(bool(v1))
# >> True
print(abs(v1))
# >> 4.47213595499958
v2 = Vector(5,7)
print(v1 + v2)
# >> Vector(7, 11)
print(v1 * 5)
# >> Vector(10, 20)

 

posted @ 2019-12-01 14:39  换头怪  阅读(225)  评论(0编辑  收藏  举报