Python类用法实例
延迟计算
使用描述器类构造延迟计算属性
- 主要目的是为了提升性能
- 避免立即计算
- 缓存计算结果供下次使用
1 | class lazyproperty: |
数据模型类型约束
使用描述器在对实例某些属性赋值时进行检查
类继承方案
基础构建模块
创建数据模型、类型系统的基础构建模块
1 | class Descriptor: |
具体数据类型
1 | class Integer(Typed): |
使用
1 | class Stock: |
装饰器类替代mixin
使用类装饰器、元类都可以简化代码,但类装饰器更加灵活
- 类装饰器不依赖其他任何新技术
- 类装饰器可以容易的添加、删除
- 类装饰器能做为mixin的替代技术实现同样的效果,而且速度 更快,设置一个简单的类型属性值,装饰器要快一倍
示例1
1 | def LoggedMapping(cls): |
示例2
1 | def Type(expected_type, cls=None): |
自定义容器
collections
定义了很多抽象基类,可以用于定义自定义基类
collections.Sequence
Sequence
需要实现的抽象方法有:
__getitem__
__len__
add
继承自其的类,支持的常用操作:索引、迭代、包含判断、切片
1 | from collections import Sequence |
collections.MutableSequence
MutableSequence
基类包括需要实现的抽象方法
__getitem__
__setitem__
__delitem__
__len__
insert
提供的可用方法包括;
append
count
:统计某值出现的次数remove
:移除某值的元素
1 | from collections import MutableSequence |
属性的代理访问
代理是一种编程模式,将某个操作转移给另一个对象来实现
需要代理多个方法时,可以使用
__getattr__
__getattr__
方法只在属性、方法不存在时才被调用, 所以代理类实例本身有该属性不会触发该方法,也不会代理 至被代理类如果需要管理所有对方法、属性的访问,可以定义
__getattribute__
,其在对类的所有属性、访问时均会 被触发,且优先级高于__getattr__
__setattr__
、__delattr__
需要约定是对代理类还是 被代理类操作,通常约定只代理_
开头的属性,即代理类 只暴露被代理类公共属性注意:对象的元信息直接访问能通过
__getattr__
代理, 但是对应的hook可能无法正常工作,如果需要,要单独为 代理类实现元信息代理方法
通过自定义属性访问方法,可以用不同方式自定义代理类行为, 如:日志功能、只读访问
- 代理有时候可以作为继承的替代方案:代理类相当于继承了被 代理类
1 | class Proxy: |
状态机(状态模式)
为不同的状态定义对象,而不是使用过多的条件判断
- 提高执行效率
- 提高代码可维护性、可读性
1 | class Connection: |
访问者模式
1 | class Node: |
yield
消除递归
消除递归一般是使用栈、队列,在python还可以使用yield
得到
更加简洁的代码
1 | import types |
字符串调用方法
- 可以使用
getattr(instance, name)
通过字符串调用方法 - 也可以用
operator.methodcaller
operator.methodcaller
创建可调用对象,同时提供所有 必要参数- 调用时只需要将实例对象传递给其即可
1 | import math |
缓存实例
工厂函数
1 | class Spam: |
缓存管理器
将缓存代码放到单独的缓存管理器中,
- 代码更清晰、灵活,可以增加更多的缓存管理机制
1 | import weakref |
__new__
1 | import weakref |