九、面向对象——类与对象

总结

为什么要用面向对象:
函数仍然无法高度的组织程序,这时候就要用面向对象

什么时候用函数,什么时候用面向对象:
当一个函数需要操作专门的数据的时候,应该封装成一个类,把数据和功能捆绑到一起

如何用面向对象:
把对象相似的东西存到类这个容器里,把对象不同的东西存到对象自己这

类的使用:
1、定义类
2、引用类的属性
3、调用类产生对象,即实例化

对象的使用:
1、引用对象属性
2、属性查找:对象---对象的类---父类
3、绑定方法的自动传值

一、对象

指的是特征与技能的结合体

面向对象编程的优点:可扩展性强

缺点:编程的复杂度高于面向过程

二、类

类是一系列对象相同的特征与技能的结合体

在程序中,必须先定义类,再调用类来产生对象,定义类的目的是为了调用类来产生对象,对象是变量+函数

定义类的语法:

class 类名:      类名用驼峰体,首字母大写

用变量表示特征,用函数表示技能

类中最常见的就是输出变量与函数的定义,但类中是可以有任意python代码的

定义函数与定义类的区别:
1、定义函数只检测语法不执行函数体代码
2、定义类会立刻执行类体代码,会产生类的名称空间,将类体代码执行过程中产生的名字都存放到类的名称空间中
3、存的目的是为了取,要想从类的名称空间中取出我们定义的名字

在定义阶段,会立刻执行类体内的代码,然后将【产生的名字】存放于类名称空间中。使用类名.__dict__查看名称空间

使用类用 . ,和模块类似,. 的前面是名称空间,. 后的叫【属性】

三、类的对象

对象由连同调用类时括号内的参数组成

类对象支持两种操作:属性引用和实例化

四、类的方法

在类内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数。self代表的时类的实例,而非类

五、__init__方法

在类内定义一个__init__函数,该函数会在调用类时自动触发执行

作用:用来在类调用阶段,为类初始化独有属性
1、该方法内可以有任意python代码

2、一定不能有返回值

六、调用类——类的实例化

调用类用(),【产生类的对象】,该对象也可以称为类的一个实例,调用类的过程也称为类的实例化

调用类(实例化)的时候发生了:

1、首先会产生一个空对象

2、会自动触发类内部的__init__函数

3、然后将空对象,以及调用类括号内传入的参数一同传给__init__函数,为对象定制独有的属性

在类内部但凡定义一个函数,都会自动传入一个self参数,对象来调的时候,会自动把自己传进来

self在定义时需要定义,但是在调用时会自动传入

self的名字并不是规定死的,但是最好还是按照约定是用self

self总是指调用时的类的实例

七、对象操作

用类名.__dict__                   查看名称空间

类名.属性                             查看

类名.属性 = 增加的内容       增加

类名.属性 = 修改的内容       修改

del 类名.属性                        删除

八、对象属性的查找顺序

先找对象自己的名称空间——再查找类的名称空间

类的数据属性,是给对象用的,而且是直接共享给所有对象用的,内存地址都一样

类的函数属性,也是给对象用的,但是给绑定对象用的,绑定到不同的对象就是不同的绑定方法,内存地址都不一样,但其实只是都是同一个功能

九、绑定方法

绑定方法的意思是类的函数属性是绑定给对象使用

绑定方法的特殊之处在于:绑定给谁,就应该由谁来调用;谁来调用,就会将谁当作第一个参数自动传入

类内部定义的函数,类可以使用,但类来用的时候就是一个普通函数,普通函数有几个参数就传入几个参数

类内部定义的函数,其实是给对象使用的,而且是绑定给对象使用的,绑定给不同的对象就是不同的绑定方法

类内部定义的变量是给所有对象共享的,所有对象指向的都是同一个内存地址

十、一切皆对象

类与类型是一个概念

十一、继承

继承是一种新建类的方式,新建的类称为子类或派生类,父类又可以基类或超类

在python中支持一个子类可以继承多个父类,子类会遗传父类的属性

继承的好处:减少代码冗余

在python3中,如果一个类没有指定继承的父类,默认就继承object

在菱形继承的背景下,查找属性:

经典类:深度优先

新式类:广度优先

寻找继承关系:继承是类与类之间的关系,寻找这中关系需要先抽象再继承

十二、派生

子类定义自己新的属性,如果与父类同名,以子类自己的为准

十三、在子类派生出的新方法重用父类的功能,也叫方法重写

方式一:指名道姓的调用(其实与继承没有关系),需要把self传进去

方式二:super()调用(严格依赖于继承)

super()的返回值是一个特殊的对象,该对象专门用来调用父类中的属性,不需要传self

super().__init__()

十四、组合

解决类于类之间代码冗余问题有两种解决方法:1、继承  2、组合

和继承相比,组合的解耦和更高,所以能用组合就用组合

继承描述的是类与类之间什么是什么的关系

组合描述的是类与类之间的关系,是一种什么有什么的关系

十五、封装

封装就是把一堆属性存起来,然后把这个属性隐藏起来

封装的目的:为了隔离复杂度。明确的区分内外,对外是隐藏的,对内是开放的。把数据属性封装起来,然后需要开辟接口给类使用,好处是可以在接口之上添加控制逻辑,从而严格控制访问者对属性的操作

在属性前面加__开头就可以把属性隐藏起来(注意不要加__结尾)

注意点:

1、其实这种隐藏只是一种语法上的变形,对外不对内

2、这种语法意义上的变形,只在类定义阶段发生一次,类定义之后,新增的_开头的属性都没有变形的效果

3、如果父类不想让子类覆盖自己的方法,可以在方法名前加__开头

发生了:
在类定义阶段将属性名统一变形:_自己的类名__属性名

property模块

用来将类内的函数伪装成一个数据属性

十六、多态

多态指的是同一种事物有多种形态,在程序中用继承来表示从属关系

多态性:可以在不用考虑对象具体类型的前提下而之间使用对象下的方法

abc模块

十七、绑定方法与非绑定方法

@classmethod:绑定方法,将类中的一个函数绑定给类

@staticmethod:非绑定方法,将类中的一个函数解除绑定

十八、反射

通过字符串来操作类与对象的属性,这种操作称为反射

内置函数

isinstance()      判断一个对象的类型

issubclass()     判断一个类是不是类一个类的子类

专门用来操作类与对象属性的函数

hasattr()     判断

getattr()    获取

setattr()    设置

delattr()    删除

十九、类内置的专有方法

__init__          构造函数,在生成对象时调用

__del__          析构函数,释放对象时使用,对象被删除的条件下,自动执行

__repr__         打印,转换

__setitem__    按照索引赋值

__getitem__    按照索引获取值

__len__           获取长度

__cmp__         比较运算

__call__          函数调用

__add__         加运算

__sub__         减运算

__mul__         乘运算

__div__          除运算

__mod__       求余运算

__pow__        乘方

__class__       用于获取当前的实例对象时哪个类

__name__      1)当文件是被调用时,__name__的值为模块名;2)当文件被执行时,__name__的值为'__main__'

二十、元类

exec()    用来处理字符串里的代码

类的类就是元类

用class定义的类使用来产生我们自己的对象的

内置元类type是用来专门产生class定义的类

用内置的元类type(),来实例化得到我们的类

type(类名,类的基类,类的字典)

自定义元类:1、来控制来的创建  2、控制类的调用过程(实例化的过程)

二十一、单例模式

单例指的是一个类的实例从始至终只能被创建一次。单例模式的主要目的是确保某一个类只有一个实例存在

实现单例模式的方法:
1、使用__new__方法

2、使用装饰器

3、使用元类

4、使用模块:python的模块就是天然的单例模式,只需把相关的函数和数据定义在一个模块中,就可以得到一个单例对象

原文地址:https://www.cnblogs.com/Python1/p/8931787.html