流程的Python 第十章:序列的修改、散列和切片

来源:互联网 发布:淘宝一元起拍在哪里 编辑:程序博客网 时间:2024/06/07 22:59

前言:
不要检查它是不是鸭子、它的叫声像不像鸭子、它的走路姿势像不像鸭子,等等。具体检查什么取决于你想使用语言的哪些行为。

目录:

  1. 内容回顾
  2. 相关资料
  3. 阅读后感

正文:
一. 内容回顾
1.1 Vector类:用户定义的序列类型

1.2 Vector类第1版:与Vector2d类兼容
承接上篇文章:流程的Python 第九章:符合Python风格的对象 对应类内置函数的改写,Vector类将初始化参数改为列表。

# -*- coding:utf-8 -*-from array import arrayimport mathclass Vector:    def __init__(self, components):        self._components = array('d', components)    def __iter__(self):        return iter(self._components)    def __repr__(self):        return 'Vector'    def __abs__(self):        return math.sqrt(sum(x * x for x in self))    def __eq__(self, other):        return tuple(self) == tuple(other)    def __bytes__(self):        return "bytes"    def __bool__(self):        return bool(abs(self))    def show_data(self):        print self._componentsif __name__ == '__main__':    myVector = Vector([3, 4, 6])    print myVector    print abs(myVector)    print myVector == [3, 4]    print bytes(myVector)    print bool(myVector)    myVector.show_data()

1.3 协议和鸭子类型

1.4 Vector类第2版:可切片的序列

# -*- coding:utf-8 -*-from array import arrayimport numbersclass Vector:    def __init__(self, components):        self._components = array('d', components)    def __len__(self):        return len(self._components)    def __getitem__(self, index):        cls = type(self)        if isinstance(index, slice):            return cls(self._components[index])        elif isinstance(index, numbers.Integral):            return self._components[index]        else:            msg = '{cls.__name__} indices must be int'            raise TypeError(msg.format(cls=cls))class MyVector:    def __init__(self, components):        self._components = list(components)    def __len__(self):        return len(self._components)    def __getitem__(self, item):        if isinstance(item, slice):            return self._components[item]        elif isinstance(item, numbers.Integral):            return self._components[item]        else:            msg = '{cls.__name__} indices must be int'            raise TypeError(msg)if __name__ == '__main__':    vector = Vector(range(7))    # print len(vector)    # print vector[2]    # print vector[-1]    # print vector[2:4]    myVector = MyVector(range(7))    print myVector[2:4]

示例中 return cls(self._components[index]) 报错信息如下:

TypeError: must be classobj, not array.array

将array用list替换,进行切片处理。

1.5 Vector类第3版:动态存取属性

# -*- coding:utf-8 -*-class Vector(object):    shortcut_names="xyzt"    def __init__(self,components):        self._components = components    def __getattr__(self, name):        cls = type(self)        if len(name) == 1:            pos = cls.shortcut_names.find(name)            if 0 <= pos <= len(self._components):                return self._components[pos]    def __setattr__(self, name, value):        cls = type(self)        if len(name) == 1:            if name in cls.shortcut_names:                error = "readonly attributes {attr_name!r}"            elif name.islower():                error = "can't set attributes 'a' to 'z' in {cls_name!r}"            else:                error = ''            if error:                msg = error.format(cls_name=cls.__name__, attr_name=name)                raise AttributeError(msg)        super(Vector, self).__setattr__(name, value)if __name__ == '__main__':    v = Vector(range(7))    print v.y    print v.x    print v.Y

1.6 Vector类第4版:散列和快速等值测试

# -*- coding:utf-8 -*-import functoolsimport operatorclass Vector:    def __init__(self, components):        self._components = components    def __len__(self):        return len(self._components)    def __eq__(self, other):        return (len(self) == len(other) and                all(a == b for a, b in zip(self._components, other)))    def __hash__(self):        hashes = (hash(x) for x in self._components)        return functools.reduce(operator.xor, hashes, 0)if __name__ == '__main__':    vector1 = Vector(range(3))    print vector1 == [1, 2]    print vector1 == [0, 1, 2]    print hash(vector1)    a = "timen.xu"    print hash(a)

1.7 Vector类第5版:格式化

# -*- coding:utf-8 -*-import itertoolsclass Vector:    def __init__(self, components):        self._components = components    def __format__(self, fmt_spec=''):        if fmt_spec.endswith('h'):            fmt_spec = fmt_spec[:-1]            coords = itertools.chain([abs(self._components)],                                     self.angles())            outer_fmt = '<{}>'        else:            coords = self._components            outer_fmt = '({})'        components = (format(c, fmt_spec) for c in coords)        return outer_fmt.format(', '.join(components))if __name__ == '__main__':    print format(Vector(range(9)))

二. 相关资料
2.1 新增_ setattr_方法,当对属性进行赋值的时候,首先会调用_ setattr_方法。在方法中对属性进行判断和保护。

三. 阅读后感
第九章和第十章都在介绍了类的很多内置方法,比如_ add_ , _ eq _等。本书名称为《流程的Python》就是讲Python内置的方法的使用,从而使得Python运行更加快速。

参考:
1. 流畅python学习笔记:第十章:序列的修改,散列和切片

原创粉丝点击