• 流畅的Python笔记(一)—python的数据模型及python风格的纸牌


    流畅的Python总览

    第一部分 序幕

    通过特殊方法,实现一个 13*4 52张的纸牌。

    第二部分 数据结构

    列表、字典和集合、文本和字节序列,用于放置数据的序列,包括了容器序列(list、tuple、collections.depue,可放置任何类型对象的引用)、扁平序列(基础类型:字符、字节、数值)

    第三部分 把函数视作对象

    将函数作为一等对象使用。python基础函数(高阶函数、匿名函数、函数式编程)、策略模式与命令模式实现的代码简化、函数的装饰器与闭包的实现。

    第四部分 面向对象惯用法

    从以下章节(对象引用、可变性和垃圾回收、符合python风格的对象、序列的修改、散列和切片、接口:从协议到抽象基类、继承的优缺点、正确重载运算符)讲解了引用(reference)的原理、“可变性”的概念、实例的生命周期、如何构建自定义的集合类型和ABC、多重继承该怎么理顺、什么时候应该使用操作符重载及其方法。

    第五部分 控制流程

    通过章节(可迭代的对象、迭代器和生成器、上下文管理器和 else 块、协程、使用期物处理并发、 使用 asyncio 包处理并发),介绍除去如条件判断、循环和子程序之类的顺序控制流程外,如何通过生成器(generator)、上下文管理器(context manager)和协程(coroutine)来介绍这些控制流程的构造,以及处理并发性(collections.futures)和面向事件的 I/O (asyncio)这些类库。

    第六部分 元编程

    通过动态属性和特性、属性描述符、类元编程,介绍到如何动态创建带属性的类,用以处理诸如JSON 这类半结构化的数据。

    本章主要记录 第一部分 序幕,也就是第一章 python数据模型。

    python数据模型

    python 3.9 文档关于数据模型的介绍,篇幅较长:数据模型

    python的魔法方法

    介绍了python的魔术方法, 它们经常是两个下划线包围来命名的(比如__init__ , __lt__, __len__). 这些特殊方法是为了被python解释器调用的, 这些方法会注册到他们的类型中方法集合中, 相当于为cpython提供抄近路. 这些方法的速度也比普通方法要快, 当然在自己不清楚这些魔术方法的用途时, 不要随意添加。

    关于字符串的表现形式是两种, __str__与__rep__ . python的内置函数 repr 就是通过 __repr__这个特殊方法来得到一个对象的字符串表示形式. 这个在交互模式下比较常用, 如果没有实现 __repr__ , 当控制台打印一个对象时往往是 <A object at 0x000> . 而 __str__ 则是 str() 函数时使用的, 或是在 print 函数打印一个对象的时候才被调用, 终端用户友好。

    两者还有一个区别, 在字符串格式化时, “%s” 对应了 __str__ . 而 “%r” 对应了 __repr__. __str__和 __repr__ 在使用上比较推荐的是,前者是给终端用户看,而后者则更方便我们调试和记录日志

    python风格代码实现的纸牌

    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]
    
    • collections.namedtuple
      Python 2.6 开始,namedtuple 就加入到 Python 里,用以构建只有少数属性但是没有方法的对象。如以上代码构建了类名为:Card,属性包含:rank 、suit的一个简单类。
    • __ getitem__ 方法
      因为__ getitem__ 方法把 [] 操作交给了 self._cards 列表,然后就把这个[]索引操作给设定下来了,因为self._cards是列表,所以列表支持索引、支持反向索引、还支持迭代 如果没有实现这个方法就会报错:‘FrenchDeck’ object does not support indexing
    • 随机抽牌 random.choice
        >>> from random import choice
    	>>> choice(deck)
    	Card(rank='3', suit='hearts')
    	>>> choice(deck)
    	Card(rank='K', suit='spades')
    	>>> choice(deck)
    	Card(rank='2', suit='clubs')
    

    纸牌排序

    import collections 
    Card = collections.namedtuple('Card',['rank','suit'])
    
    # 定义花色大小
    suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)
    
    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]
    
        # 排序函数
        def spades_high(card):
    		rank_value = FrenchDeck.ranks.index(card.rank)
    		return rank_value * len(suit_values) + suit_values[card.suit]
    
    • 纸牌排序
      FrenchDeck 是不能洗牌的,因为这摞牌是不可变的(immutable):卡牌和它们的位置都是固定的,除非我们破坏这个类的封装性,直接对 _cards 进行操作。

    个人博客:Loak 正 - 关注人工智能及互联网的个人博客
    文章地址:流畅的Python笔记(一)—python的数据模型及python风格的纸牌

  • 相关阅读:
    HackerRank savita-and-friends
    HackerRank training-the-army
    51Nod 1378 夹克老爷的愤怒
    51Nod 1380 夹克老爷的逢三抽一
    Codeforces 566 D. Restructuring Company
    BZOJ 2822: [AHOI2012]树屋阶梯
    Codeforces Gym 101138 G. LCM-er
    51Nod 1250 排列与交换
    BZOJ 1511: [POI2006]OKR-Periods of Words
    BZOJ 1355: [Baltic2009]Radio Transmission
  • 原文地址:https://www.cnblogs.com/l0zh/p/13739731.html
Copyright © 2020-2023  润新知