数据结构
- list
插入:insert(index, item), append(item)
删除:pop(index), remove(item)
合并:extend(List)
- dict
插入:update(Dict)
删除:popitem(), pop(key), del
合并:update(Dict)
- set
插入:add(item), update(iterable)
删除:remove(item), pop()
合并:union(Set), update(Set)
- deque
插入:insert(index, item), append(item), appendleft(item)
删除:pop(index), popleft(), remove(item)
合并:extend(List), extendleft(List)
- heapq
插入:heapq.heappush(List, item)
删除:heapq.heappop(List)
合并:heapq.merge(*iterable)
语法知识
主要从《Python3 Cookbook》总结。
函数
- 1, 匿名函数的外部变量是运行时绑定,不是定义时绑定,所以要达到定义时绑定,需要外部变量移到参数位置如
lambda x=x: pass
; - 2, 使用partial创建一个预赋参数的函数;
- 3, 使用闭包(内部函数)比单个方法的类更简洁;
类和对象
- 1,
__repr__
,repr(obj)
,__str__
,str(obj)
, 改变对象的字符串显示; - 2, 使用
__format__
自定义对象的格式化; - 3,
__enter__
(返回值作为as后的变量),__exit__
让对象支持上下文管理协议, 结合yield
和contextlib
里面的contextmanager
也可以; - 4, 在类中定义
__slots__
创建大量对象时节省内存; - 5, 单下划线使方法变为内部实现,_双下划线使父类属性变为私有,继承后子类属性名字变为
_Super__attribute
; - 6, 使用类(实现
__get__
,__set__
,__delete__
),property(getter, setter, deleter, doc)
,@property(@attr.setter, @attr.deleter)
等方法实现属性描述符; - 7,
super()
调用mro列表里的类的方法,通常是父类方法。在__getattribute__
,__setattr__
避免无限递归时也可使用; - 8, 继承property后如果要扩展,要么全部方法自己实现一遍,如果要只扩展一个方法,需要对应方法的装饰器改为
@Super.attr.setter
; - 9, 使用类描述器可以实现大部分Python类特性,如
@classmethod
,@staticmethod
,@property
,__slots__
等; - 10, 使用类描述器(或函数装饰器+
@property
),通过拦截读取调用__get__
方法可以实现所谓的lazy计算; - 11, 在父类实现
__init__
,子类没有__init__
,子类实例化时就只调用父类的__init__
; - 12, 实现抽象基类(类似go中的接口),使用
@abstractmethod
和abc
模块的ABCMeta
:
from abc import ABCMeta
class ABC(metaclass=ABCMeta):
@abstractmethod
def read():
pass
抽象基类不可实例化,抽象基类可以用来在其他地方判断一个对象是不是某种类型,从而判断它是否有相应方法。
还可以使用Super.register(Super.Super)
来注册实现抽象基类;
- 13, 实现类数据模型的类型约束这样任务,可以使用描述器,类装饰器,元类;
- 14, 继承并实现
collections
模块的抽象基类,可以实现自定义容器; - 15, 在当前类中利用一个别的类的实例,实现
__getattr__
,__setattr__
,__delattr__
,找不到当前类的属性时调用,返回实例的属性,即可实现代理类; - 16, 实例化一个类时,还可以在某个类方法使用
cls(*args, **kwarg)
返回实例进行实例化; - 17, 实例化一个类时跳过
__init__
,使用cls.__new__(cls)
或Cls.__new__(Cls)
可得到一个没有属性的实例; - 18, 继承一个Mixin类,或者通过类装饰器实现一个Mixin,可以为类添加一些方法;
- 19, 使用不同状态的类,内部维护这一个状态类,方法接口对对应到这个状态类的方法接口,实现状态模式;
- 20, 使用
getattr(instance, 'attr')
获得属性,如果是函数属性可以接着调用,也可以使用operator.methodcaller('attr', *vars, **kwargs)(obj)
; - 21, 使用
functools.total_ordering
可以简化类之间的比较,只需实现__eq__
,__lt__
即可自动补充其他比较方法; - 22, 使用
weakref.WeakValueDictionary()
作为缓存保存单例,这样既不会给单例增加额外的引用,也可以实现单例的功能;
元编程
- 1,使用
@wraps
可以保留被装饰函数的__name__
,__doc__
,__annotations__
等元信息,被装饰函数在__wrapped__
里,python3.3, python3.4+的__wrapped__
结果不一样,后者是遇到多层装饰器需要剥开多层__wrapped__
; - 2, 带有参数的装饰器可以有两种写法;
- 3,
inspect
模块可以查找函数对象的信息; - 4, 可以把类的实例方法,类方法定义成装饰器,使用时实例装饰器需要实例化,类装饰器直接使用
@类名.decorator
;