python中有很多关于类的内置函数和方法,这部分的知识,自己也是一直拖着没去总结,这周抽出时间写一篇总结类的博客。
基本方法
对于一个普通对象而言,它有以下常用的内建方法:
__class__: 创建此对象的类
__init__: 初始化对象,在创建的时候被调用。
注意这并不是严格意义的构造函数,只能说是在初始化的时候,会被调用的钩子函数。
那么说道这个方法,就有必要提到调用父类构造函数常用到的函数:super函数,这个函数可以方便的调用父类的构造函数,super(ChildObject, self).__init__(),不用提及父类名。
__del__: 释放对象,在对象删除的时候被调用。
__str__: print 的时候会被调用(给人看的)。
__repr__: 给机器看的字符串。
既然说到了类方法,那么不得不提到,__new__方法。
实际上new才算是python对象的构造函数,用于生成实例对象,我们看见的单例模式,就是在这个函数上做文章。
1 | class Singleton(object): |
在python中,类也是对象,所以对于一个类对象而言:
__class__: 类也是对象,类的class是type.
__name__: 类的名称
__doc__: 类的文档,在使用help的时候会拿出来。
__mro__: mro即method resolution
order,主要用于在多继承时判断调的属性的路径(来自于哪个类)(这里还可能会提到: 深度优先搜索算法 )
访问对象属性。
python对象中有一个内建属性,__dict__,所有python对象的属性,都放在这里,比如你有一个对象a,它有一个属性 a.b == 5,那么你也一定能在a.__dict__["b"]中访问到它。
你可以用这两个内建函数,以字符串路径引用的方式从一个对象中获取属性和方法(方法也算是属性。)
1 | getattr |
1 | class A(object): |
一些钩子函数
__getattr__为内置方法,当使用点号获取实例属性时,如果属性不存在就自动调用__getattr__方法,你可以定义它返回一个值,或者抛出一个异常。
如果你需要一个在每一个属性访问的钩子时, __getattribute__() 可以满足。钩子的顺序是先调用__getattribute__(),再调用__getattr__,
还有一点需要注意的是,当使用类访问不存在的变量是,不会经过__getattr__函数。
__setattr__当设置类实例属性时自动调用。
描述符
描述符是一个一开始很难理解的东西,你如果看见一个类中定义的属性,不是在__init__中定义的,而是像java那样的声明式定义,那就很可能是一个描述符。
作为描述符对象,需要实现以下方法:
__set__: 在任何特性被设置的时候调用。
__get__: 在任何特性被读取的时候被调用。
__delete__: 在特性被del的时候被调用。
普通python对象的属性,都是在__dict__上进行操作的,但是Description就不同了,这个东西在被对象作为属性访问的时候,就不是通过dict来访问的,而是调用Descriptor的__get__, __set__, __delete__.
你看这个应该很熟,首先在python的@property装饰器描述符,就是通过Description实现的。
在django-orm和sqlalchemy orm中,定义字段,也是在使用描述符。
1 | class User(Base): |
容器对象
__getitem__(self,key),这个方法实际上就是对应 seq[key]
可迭代对象
__iter__: 返回迭代器自己
next(): 返回迭代后的下一个值,这个函数是以前版本的兼容,python3中,必须实现一个__next__方法。
其它方法
__cmp__ 看命名就知道排序会用到这个方法。
__gt__ 判断self对象是否大于另一个对象。
__lt__ 判断self对象是否小于另一个对象。
__ge__ 判断一个兑现是否大于等于另一个对象。
__le__ 判断一个对象是否小于等于另一个对象。
__eq__ 判断一个对象是否等于另一个对象。
__call__ 让一个对象可以被调用。