使用__slots__
- 给实例绑定的方法,对其他实例不生效,只有给类绑定的方法,才对所有实例生效
类的方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能 - __slots__变量,可以限制class实例能添加的属性
- class Student(object):
__slots__ = ('name','age')
#用tuple定义允许绑定的属性名称 __slots__
定义的属性仅对当前类实例起作用,对继承的子类是不起作用的- 因为子类可以自己再重新定义
- 除非在子类中也定义__slots__,这样子类实例允许定义的属性就是自身类的__slots__和父类的__slots__
- class Student(object):
使用@property
- 在绑定属性的时候,如果直接把属性暴露出去,虽然写起来简单,但是没有办法检查参数,导致参数可以随意改
- 可以通过增加set_属性、get_属性方法,来限制属性的输入
- @property装饰器负责把一个方法变成属性调用
- 应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查
- 这样,程序运行时就减少了出错的可能性
- 属性的读写
都定义,是读写属性 - 先定义@property(是getter方法)
- 再定义@属性名.setter (是setter方法)
- 只定义getter方法,不定义setter方法,属性就是一个只读属性
即只用@property ,不用@属性名.setter
- 只定义getter方法,不定义setter方法,属性就是一个只读属性
- 总结
- 把一个get方法变成属性,只需要加上@property装饰器就可以了
- 此时,@property本身又创建了另一个装饰器@属性名.setter,负责把一个setter方法变成属性赋值
- 于是,就创建了一个可控的属性操作
多重继承
- 继承是面向对象编程的一个重要方式,因为通过继承可以扩展父类的功能
- 多重继承是指一个类可以继承多个类,用逗号分隔
class Bat(Mammal,Flyable):
pass
通过多重继承,一个子类可以同时获得多个父类的所有功能
- MixIn
- 在设计类的继承关系时,通常主线都是单一继承下来的,但是,如果需要‘混入’额外的功能,通过多重继承可以实现,这种设计称之为MixIn
- MixIn的目的就是给一个类增加多个功能,这样在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn,而不是设计多层次的复杂继承关系
定制类
__init__
:用于类绑定部分属性__slots__
:限制类的实例的属性__len__()
:让类作用于len()函数__str__
:返回用户能看到的字符串__reper__
:返回程序开发者看到的字符串(为调试服务)- 通常
__str__
和__reper__
代码一样,所以可以先定义一个,然后再赋值给另一个
__iter__
:返回可迭代对象,实现类像list或tuple一样被for…in循环- 该方法返回一个迭代对象,然后python会不断调用该迭代对象的
__next__()
方法拿到循环的下一个值
python2.7中是next()方法 - 直到遇到StopIteration错误时退出循环
- 该方法返回一个迭代对象,然后python会不断调用该迭代对象的
__gentitem__
:让class实例像list一样可以使用索引和切片__gentattr__
:动态返回一个属性或函数,避免调用不存在的属性的报错__call__
:实现实例本身的调用- 总结
- python的class允许定义许多定制方法,方便生成特定类
- 更多定制方法 https://docs.python.org/3/reference/datamodel.html#special-method-names
使用枚举类
- 用大写变量通过整数来定义常量
- 例如月份:JAN = 1
- 缺点是类型是int,并且仍然是变量
- 更好的方法是为这样的枚举类型定义一个class类型,然后每个常量都是class的一个唯一实例
- python中用Enum类实现
- Enum可以把一组相关常量定义在一个class中,且class不可变,而且成员可以直接比较。
使用元类
- type()
- type()可以查看一个类型会变量的类型
- 类的定义是运行时动态创建的,而创建class的方法是使用typeI()函数
- type()函数可以既可以返回一个对象的类型,又可以创建出新的类型
- 先定义函数,再通过type()创建类
def fn(self,name = ‘world’):
print(‘hello,%s’ % name)
Hello = type(‘Hello’,(object,),dict(hello=fn)) - 需要依次传入三个参数
class名称
继承的父类集合(支持多重继承),单个时最后加,号
class的方法名称
- 先定义函数,再通过type()创建类
- 通过type()创建的类和直接写class是完全一样的,因为python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class
- metaclass
- metaclass直接翻译为元类
metaclass允许创建类或者修改类,即可以把类看成是metaclass创建出的‘实例’ - https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319106919344c4ef8b1e04c48778bb45796e0335839000
- metaclass直接翻译为元类