对python参考手册第四版,第七章学习总结
1. 关于OOP
编程语言是用于解决问题的工具,将现实世界的问题在计算机上建模,通过编程语言事先编写执行指令,通过计算机的强大能力运行解决。编程过程中有多种模式,各模式没有绝对的好坏之分,只是需要应用在最佳的使用场景。对于小规模问题、初学编程时,使用面向过程可以快速编码。对于大型规模的程序,可以使用OOP的模式来编码。OOP提供了一些好处,当然也有自己的缺点。OOP的好处之一是提供了模块化,将几十万甚至几百万行代码通过不同的设计分门别类,整个程序的组成划分成不同的模块,每个模块有各自的功能,这样方便:调试、维护、扩展、修改、查找等。
2. 关于容器
python中很多对象都可以被理解成容器。
列表:按顺序存放数据,根据下标索引来增删改查,容器。
元组:不可修改的列表,容器。
字符串/数字/bool值这些不可变对象:它们基本都使用变量名来指向,即 a = 2,的意思是,创建一个变量名叫a,指向内存中某一个位置上的数字2,某些角度上,变量名就是一个容器(也可以理解成指针)
字典:存放键值对,通过键来增删改查,容器。
函数:函数名可以认为是函数代码的标题、标签,也可以认为是容器,里面存放函数执行代码。
模块:存放各种变量、函数、类等等,容器。
如果按照容器的角度来理解python中各对象,那么class也是一种容器。
类:存放属性、方法,使用类名/对象名.xxx 的形式来访问,容器。
3. class语句
class语句
定义了一类对象的通用/共有属性或者方法,class定义的内容只是模板。class顺带还定义了命名空间,即缩进的内容全部归属于本class。
一般按照如下方式定义一个基本的class:
class Student(object):
student_count = 0
def __init__(self, name, age):
self.name = name
self.age = age
def show_name(self):
print(self.name)
在这个类定义中:
1、指定类名并表明继承的对象,至少继承至object,因为所有类都是object类的子类。
2、定义了一个类变量,该类变量是归属类所有,一般使用Student.student_count
来访问,但是也可以被实例访问
3、定义了特殊函数__init__
,因为是特殊函数所以已经有内在的定义,该函数是实例的初始化函数。
4、定义了一个实例方法show_name,其实__init__
的函数性质也是实例方法,所谓实例方法,就是指在定义的时候就被设计成以后要被实例对象所调用。在类中定义的方法,默认情况下都是实例方法。也就是说,只要是在类中按照如上方法定义的方法,都会被认为是后续实例要调用的。而所有实例在调用自己的实例方法的时候都会将自身作为参数传入实例方法,所以实例方法在定义的时候第一个参数用于指代实例对象自身,按照约定俗成是self,其他别的也行,只是一个代号而已。 所以如上代码定义的内容就是:类变量 + 实例方法
4. 类实例
如果只是定义类的内容,并没有太大的作用,因为类只是定义了一个通用的模型/模板/蓝图,需要实际的、真实的、具象的、具体的对象(也叫实例,一个东西)在程序中相互作用完成程序的执行。
类可以被call,也就是说类可以被执行,就像某一个函数可以被执行一样,函数会返回值,而类也一样。
student = Student(*args, **kw) #通过()来调用/执行一个类,会返回一个对象。
student = Student('xiaoming', 26)
类对象生成过程有几点注意:
1、Student类会首先执行__new__
特殊函数,生成一个对象xx,该对象属于Student类
2、调用__init__
函数,不论是否显式定义,该函数作用是对xx对象进行初始化。如果显式定义,则使用*args, **kw的内容来对xx对象进行初始化:
self.name = 'xiaoming' , self.age = 26
3、将Student类中所有实例函数都copy给xx对象,也就是说: self.show_name = show_name,此时xx对象除了有属性,还有方法了
4、返回xx对象,此时该对象已经有name和age属性(xx对象也可以认为是一个容器),并赋值给student变量,或者说,使用student变量来指向此xx对象
5. 疑问
如何使用对象、实例?
对象使用.来访问自己拥有的属性或者方法,如尝试访问student.height
, 首先在自身空间寻找该属性,没有找到的话就在类空间寻找,还是未找到,继续在基类空间寻找,最终未找到则抛出错误。
关于为啥使用self指代自身?
书上的含义是说:首先,python不像java或者c是静态类型,python是动态类型,在student.show_name这个函数中,python无法区分一个普通的函数局部变量name 和 实例的name属性。所以使用self.name来表示实例对象的name属性,而普通的name变量则意味着是函数中的局部变量。所以所有实例方法都需要self参数。