• 流畅的python学习笔记:第一章


    这一章中作者简要的介绍了python数据模型,主要是python的一些特殊方法。比如__len__, __getitem__. 并用一个纸牌的程序来讲解了这些方法

    首先介绍下Tuple和nametuple的区别:

    Nametuple是类似于元组的数据类型。除了能够用索引来访问数据,还支持用方便的属性名来访问数据。

    传统的元组访问如下。对每个元素的访问都必须通过索引来找到。这种找法很不直观

    tup1=('abc','def','ghi')
    print tup1[1]

    使用nametuple来构造:

    tup2=namedtuple('tuple2',['name','age','height'])
    t1=tup2('zhf','33','175')
    print t1
    print t1.age
    print t1.height
    print t1.name
    得到结果如下,namedtupel中tuple2是类型名,name,age,height是属性名字
    从上面的访问可以看到,直接用t1.age的方法访问更加直观。当然也可以用索引比如t1[0]的方法来访问

    namedtupe1也支持迭代访问:

    for t in t1:
        print t
    和元组一样,namedtupel中的元素也是不可变更的。如果执行t1.age+=1。将会提示无法设置元素

    Traceback (most recent call last):

      File "E:/py_prj/fluent_py.py", line 17, in <module>

        t1.age+=1

    AttributeError: can't set attribute

    下面来看下书中的纸牌例子,代码如下:

    from collections import namedtuple

    Card=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]

    if __name__=='__main__':
        deck=FrenchDeck()
        print len(deck)
        print deck[1]

    首先定义了的纸牌元组Card, rank代表纸牌数字,suit代表纸牌花色。然后在FrenchDeck首先定义了ranks和suit的具体指。在__init__中对self._cards进行初始化。

    __len__反馈self._cards的长度。__getitem__反馈具体的纸牌值。

    结果如下,纸牌的长度为52,其中deck[1]为Card(rank=’3’,suit=’spades’)

    可以看到len(deck)其实调用的是__len__方法。deck[1]调用的是__getitem__

    由于有了__getitem__方法,还可以进行迭代访问,如下:

    for d in deck:
        print d

    既然是可迭代的,那么我们可以模拟随机发牌的机制。

    from random import choice
    print choice(deck)

    得到结果:

    Card(rank='9', suit='hearts')

    接下来看另外一个例子,关于向量运算的。比如有向量1 vector1(1,2),向量2 vector2(3,4)。那么vector1+vector2的结果应该是(4,6)。Vector1和vector2都是向量,如何实现运算呢。方法是__add__,__mul__

    代码如下:

    class vector:
        def __init__(self,x=0,y=0):
            self.x=x
            self.y=y
        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)
    if __name__=='__main__':
        v1=vector(1,2)
        v2=vector(2,3)
        print v1+v2
        print abs(v1)
        print v1*3

    运算结果如下:

    在这里__add__,__mul__,__abs__分别实现了向量加法,乘法,以及求模的运算。

    值得一提的是__repr__的方法。这个方法是在需要打印对象的时候调用。例如print vector(1,2)的时候得到vector(1,2). 否则就是表示对象的字符串:<Vector object at 0x0000>.这个__repr__和__str__的作用是类似的

    
    
  • 相关阅读:
    springboot jpa junit测试遇到的问题
    解决Eclipse中.properties文件中文乱码问题
    java 学习笔记(五) Zookeeper的集群配置和Java测试程序
    Kotlin编译器使用及反编译分析
    Kotlin重新学习及入门示例
    SATB的标记问题解决之道与G1垃圾收集模式系统详解及最佳实践
    SATB深入详解与问题剖析【纯理论】
    三色标记算法在并发情况下的漏标问题分析【纯理论】
    G1混合式GC与三色标记算法详解【纯理论】
    G1垃圾收集器深度理论讲解【纯理论】
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/7011435.html
Copyright © 2020-2023  润新知