7.1class语句
类是创建新对象的机制
定义了一组
属性
方法method
类变量class var:所有类实例对象间共享
特性property
类主体执行期间创建的值放在类对象中,对象充当命名空间,类似于模块
7.2类实例
类实例:(以函数形式) 调用类对象 创建
__init__内,将属性分配给self,将之保存在实例中
类属性——实例属性
点运算符:属性绑定
访问实例的属性:搜索实例——搜索类
7.3作用域规则
类会定义命名空间
但不会为 方法中使用的名称 创建作用域
所以在实现类时,对属性与方法的引用必须是完全限定。通过self引用实例对象
类中没有作用域
显式使用self(对应于c++的this):因为python没有提供显式声明变量的方式
无法区分要赋值的变量是局部变量还是实例对象的属性**
存在self中的是实例属性,其他赋值为局部变量
7.4继承:创建新类的机制
属性:继承,添加,重定义
,,分隔基类名称列表
继承功能是用 功能稍增强的 .属性搜索实现的
覆写不会自动调用原方法,包括初始化函数
继承的实现:.运算符增强,实例——类——父类属性搜索
调用父类方法
1.直接用父名限定(不一定由父类实现)
2.super(cls,instance)
简写
super().func(args)
super返回特殊对象,支持在基类寻找属性(.)
多重继承:属性解析变复杂
解析不一致:拒绝创建类
mixin类:混入其他类中的一组方法,添加功能(与宏相似)
混合类中的方法假定其他方法存在,然后对功能增强
直接用类名引用属性
去self引用导致的歧义
7.5多态动态绑定与鸭子类型
继承背景下的动态绑定
不考虑类型情况下使用实例
由继承属性查找过程处理
绑定过程不受obj类型影响
鸭子:创建自定义对象,不选择继承,而是实现外观与行为
保持程序组件的松耦合
7.6静态方法与类方法
类定义中,所有函数假定在实例上操作,以self传递实例
@staticmethod
静态方法:不对实例操作
用于创建实例的非构造器方法
与类也无关?
@classmethod
类方法
调用合适类型的方法,创建合适类型的类对象实例
静态方法,类方法与实例方法同用命名空间
可由实例调用
7.7特性
访问时计算值
@property
属性的形式访问方法
统一访问规则,同名属性:先特性,再属性
不需添加额外的调用操作符
方法作为隐式的特性处理
创建实例,访问方法
得到绑定方法,而非原始函数对象
特性可截获操作权,设置,删除属性
通过向特性附加setter,getter方法
def __init__(self,name):
self.__name=name
@name.setter
def name(self,value)
__name=
实际存储属性名与特性名必须不同
特性函数中修改实际存储属性名
7.8描述符
使用特性,对属性的访问将由用户定义的get,set,delete控制
属性控制方式可通过描述符对象进一步泛化???
描述符对象:代表属性值的对象
属性值:内置对象——类对象——类对象实现访问控制
解耦合
描述符(类型)只能在类级别上实例化(属性)
实现方法__method__
get,set,delete
委托给getattr,setattr???
为了让描述符在实例上存储值,选择本身所用名称不同的名称
7.9数据封装与私有属性
默认情况下类的属性是公共的,可能导致命名冲突
__开头的变量自动变形,_Classname__Foo
提供了类中添加私有变量的方式
变形过程只在定义类时发生一次
重定义__dir__()方法,降低可见性
建议在定义可变属性时,通过特性使用私有属性
__为方法提供私有名称,阻止派生类重新定义或修改
不要混淆私有类属性命名与模块“私有”定义命名
7.10对象内存管理
定义类后,得到创建新实例的工厂
实例创建包括两步:__new__ 创建新实例 __init__实例初始化
__new__ 用于
1.继承自基类,基类的实例不可变
2.定义元类
实例由引用计数管理
__del__销毁实例
weakref:为一个类创建 对其他类的弱引用
弱引用访问时,检查对象是否存在
7.11对象表示与属性绑定
内部实现:实例由字典实现
__dict__访问字典
任意时刻可以添加属性
__class__链接回类
类本身也是字典的浅层包装
__base__链接回基类
对于实例
增删改查,隐式调用__getattribute__(检查特性,搜索实例字典,类字典,递归搜索 优先级),__setattr__,__delattr__
与字典无关??
参数(self,attrname)
请求的属性是特性,描述符,执行相关
通用包装器,现有对象的代理
使用属性访问运算符,重定义
7.12__slots__ 限制合法属性名称
不是作为安全特性,而是作为内存与执行速度的优化
基于定长数组保存属性
继承自实现slots的基类,需要实现自己的slots
破坏依赖__dict__属性的行为
7.13运算符重载
每个运算符的实现中显式处理类型转换
7.15类型与类成员测试
测试对象是否为类型(或其派生)的实例
isinstance(obj,cname)
issubclass()
重定义函数行为
__instancecheck__
__subclasscheck__
register()集合中注册新类
更正式的机制
分组对象,定义接口并进行类型检查
7.15抽象基类
定义抽象基类,使用abc模块
模块定义了一个元类ABCMeta
一组装饰器@absractmethod @abstactproperty
class Foo(metaclass=ABCMeta)
@absractmethod
@abstactproperty
抽象类的实现离不开元类
装饰器指定的方法与特性必须由子类实现
不会检查参数与返回值
抽象基类支持已存在的类进行注册,不会检查该类是否实现了抽象方法与特性
7.16元类
定义类时,类本身成为对象(鸡蛋问题)
元类:特殊对象:创建类对象
创建与管理类
元类: 名为type的类
class语句定义新类时的行为
局部字典class_dict
在其中执行类主体class_body
exec(class_body,globals(),class_dict)
创建类对象
Foo=type(class_name,class_parents,class_dict)
类主体在私有字典中为一系列语句(代码)
执行类主体
私有成员名称变形
类的名称,基类列表,字典 传递给元类的构造函数,创建相应类对象
最后,调用元类type(),此步可自定义:
类可指定元类(metaclass=type)
没有显示元类,检查基类元组第一个条目
没有指定基类,检查全局变量__metaclass__
默认元类type()
元类行为:
额外检查,不更改创建的内容
高级元类:
创建类之前,检查、更改类定义的内容
重新定义__new__方法:用描述符、特性包装属性
自定义元类,继承type,重新实现__new__ 或 __init__
7.17类装饰器
定义类后执行额外处理,注册等动作
接受类作为输入,返回类