第七章:类与面向对象编程——参考手册笔记

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类装饰器

定义类后执行额外处理,注册等动作

接受类作为输入,返回类

原文地址:https://www.cnblogs.com/qmcj/p/9111526.html