zoukankan      html  css  js  c++  java
  • 流畅的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)
  • 相关阅读:
    【转】编写高质量代码改善C#程序的157个建议——建议70:避免在调用栈较低的位置记录异常
    【转】编写高质量代码改善C#程序的157个建议——建议69:应使用finally避免资源泄漏
    【转】编写高质量代码改善C#程序的157个建议——建议68:从System.Exception或其他常见的基本异常中派生异常
    【转】编写高质量代码改善C#程序的157个建议——建议67:慎用自定义异常
    Arrays数组工具类中存在的坑!
    java.util.ArrayList
    java.util包下面的类---------01---示意图
    elasticsearch从入门到出门-08-Elasticsearch容错机制:master选举,replica容错,数据恢复
    elasticsearch从入门到出门-06-剖析Elasticsearch的基础分布式架构
    CentOS7.1安装 Vsftpd FTP 服务器
  • 原文地址:https://www.cnblogs.com/lw-monster/p/11965996.html
Copyright © 2011-2022 走看看