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

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

目录:

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

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

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

# -*- coding:utf-8 -*-
from array import array
import math

class 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._components

if __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 array
import numbers


class 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 functools
import operator


class 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 itertools


class 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学习笔记:第十章:序列的修改,散列和切片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值