第一章 python风格

流畅的python第一章的主要目的就是讲解python风格,用了一摞纸牌来介绍,并且其中包含了一些特殊函数的用法
总的来讲主要就是通过一个例子让大家了解到python的设计思想,让我来说就是,通过重视函数让核心功能更加容易使用的思想,更加玄学但简明的表达是len( collections) 而不是 collections.len 的思想

这里就不再抄一摞纸牌的源代码了,只通过半仙儿的理解,简化一下代码,让作者最想表达的东西更容易看出来,如下:

class Friends(object):

    def __init__(self):
        self.friends = [1, 2, 3, 4, 5, 6]
        self.index = 0

    def __len__(self):
        return len(self.friends)

    def __getitem__(self, position):
        return self.friends[position]
a = Friends()
for item in a:
    print item,
    
执行结果
1 2 3 4 5 6

通过上面的写法可以看出,给类写上了__len__()__getitem__()方法,这个类就直接能够被当作数组使用了,for loop 也是可以直接进行迭代的, 甚至可以直接使用a[index]来打印其中的值.
其中的原因就在于a[index]调用的就是a.__getitem(Index),而for loop会通过两种方式来进行迭代,一种是通过len - getitem,另一种是通过__iter__ - next,后一种方式已经在半仙儿之前的博客内讲过,没看过先去看并且点赞python简单进阶,Iteration
其中主要的意思就是如下

class Friends(object):

    def __init__(self):
        self.friends = [1, 2, 3, 4, 5, 6]
        self.index = 0
        
    def __iter__(self):
        return self.friends.__iter__()

    def next(self):
        while True:
            if self.index >= len(self.friends):
                raise StopIteration
            else:
                save = self.index
                self.index += 1
                return self.friends[save]
a = Friends()
for item in a:
    print item, 
print a[0]

执行结果
1 2 3 4 5 6
TypeError: 'Friends' object does not support indexing

原理之前的博客都已经讲过,最后报了TypeError的错误,原因在于a[index]调用的就是a.__getitem__(index)方法.
通过上述例子是不是对python的思想有所了解?内置方法都是通过调用类的内部的某些特殊函数来进行实现的这种思想,这种len( collections ) 而非 collections.len的思想

当然了第一章也讲了一下其他的东西,如下:

  1. 有名tuplecollections.namedtuple( 'name', ['filed1', 'filed2', ...])

    import collections
    Card = collections.namedtuple('Card', ['rank', 'suit'])
    c = Card(1, 2)
    print c.suit
    
    执行结果
    2
    
  2. sorted排序,关键通过key和reverse两个参数让排序的使用方便灵活
    其实sorted和sort一样,这里简要的介绍一下
    iterable.sort( cmp, key, reverse)和sorted(iterable,cmp, key, reverse)
    一看就很清楚了,iterable.sort()是改变自身的顺序,而sorted()是不改变自身的顺序,而返回一个新的排好序的iterable(如列表等可迭代对象)
    其中cmp的用法没有仔细用过,不过key很好用,如果只是数组本身存的是数的话,不用指定key,如果数组中存的是对象的话,指定一个排序的依据就行,如下

    import collections
    test = collections.namedtuple('TestOject',['name', 'value'])
    a = [test('1', '1'), test('2', '2'), test('3', '3'), test('4', '4')]
    # 按照value降序
    print sorted(a, key=lambda x: x[1], reverse=True)
    # 按value升序
    print sorted(a, cmp=lambda x, y: x[1] > y[1])
    

    当然了,有关lambda的用法,半仙儿在之前的博客中已经非常详细的讲过了python lambda详解

  3. 运算符重载和一些其他的内置函数

    class Vector(object):
    
        def __init__(self, x=0, y=0):
            super(Vector, self).__init__()
            self.x = x
            self.y = y
    
        # +运算符重载
        def __add__(self, other):
            x = self.x + other.x
            y = self.y + other.y
            return Vector(x, y)
    
        # 乘运算符重载
        def __mul__(self, other):
            return Vector(self.x * other.x, self.y * other.y)
    
        # abs的调用
        def __abs__(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
    
        # 减运算符重载
        def __sub__(self, other):
            pass
    
        # 除运算符重载
        def __div__(self, other):
            pass
    
        # 字符串表示形式
        # str() 和 print 调用  __str__
        def __str__(self):
            return 'Vector({0}, {1})'.format(self.x, self.y)
    
        # python 需要调用__str__()而没有的时候,会调用__repr__()
        def __repr__(self):
            return 'Vector({0}, {1})'.format(self.x, self.y)
    
    
    a = Vector(3, 4)
    b = Vector(3, 4)
    print abs(a + b)
    print type(a + b)
    print a + b
    print str(a + b)
    
    test_one = [1, 2, 3, 4, 5, 6, 1, 2, 3]
    # 计算一个value在list中出现了多少次
    print test_one.count(1)
    
    执行结果
    10.0
    <class '__main__.Vector'>
    Vector(6, 8)
    Vector(6, 8)
    2
    

第一章总结就是
通过实现特殊方法,自定义数据类型可以表现的跟内置类型一样,从而写出更具有表达力的代码,或者说更具有风格的代码

猜你喜欢

转载自blog.csdn.net/qq_40666620/article/details/108315472
今日推荐