知识点1:预备知识
1.关于面向对象的简单定义和介绍:
- 一个程序是由许多共同合作的对象组成的;
- 每一个对象都是一个小的“岛屿”,与别的对象合作工作,而并不是成为“整个程序”;
- 一个程序是由许许多多的对象组成共同工作完成的,各个对象之间可以相互使用对方的功能。
2.定义与举例说明
Class-模板(templete)
Method or message-类的规定好的功能(A defined capability of a class)
Field or attribute-类中的一系列数据(a bit of data in a class)
Object or Instance-类的特定实例(a particular instance in a class)
举例说明,字符串(string)是一种class,.uppercase就是一种method,当中的数据就是attribute。
Class是用来描述一类事物的东西,他们具有哪些特征,是一个蓝本,而Object则是描述的一个个体。例如狗是一个Class,那么我们看到的每一条狗,都是一个Object。
知识点2:Class和Object/Instance
举例进行理解,Class是一种模具,一种蓝本,表征某种事物的特征群体,而Object/Instance是指的实实在在的具体的个体,Object和Instance在使用的时候经常也是可互换的。
知识点3:Method/Message
>>> x = 'abc'
>>> type(x)
<class 'str'>
>>> type(2.5)
<class 'float'>
>>> type(2)
<class 'int'>
>>> y = list()
>>> type(y)
<class 'list'>
>>> z = dict()
>>> type(z)
<class 'dict'>
在以上这段代码当中,x就是一个str Class中的Object/Instance
>>> dir(x)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> dir(y)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> dir(z)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
以上代码当中,输出的就是Method/Message.
知识点4:Building a class in python
学习本知识点的目的是让体会构造一个类的体验,而不是专门去写这样的代码。类似代码都有专人去完成,我们需要做的就是会更好地直接利用这些嵌在python中的类。
以下详细解读一下这张ppt的内容:
- 其中,partyanimal是一个类(class),x是一个参数(attribute),an是一个对象(object),这个object是利用partyanimal这个模具(template)做成的;
- def那一段的代码块,代表的是class的方法(method);
- an = PartyAnimal()这样的代码其实接触过很多回,就是类似于x = list()这样的操作;
- 最后call的操作,可以等效为右侧的形式,在call的时候,party()没有传入参数,因此,对应上面的def模块,可以看出来其实现的功能是an.x = an.x + 1
知识点5:具体Class程序的运作流程与实现
class PartyAnimal:
x = 0
def party(self):
self.x = self.x + 1
print('So far' , self.x)
an = PartyAnimal()
an.party()
an.party()
an.party()
程序的输出结果为:
So far 1
So far 2
So far 3
程序的解读如下:
- an是一个object,这个object的self当中包含了一个attribute-x,以及一个method-party()。【可能会有更多的参数吗?】
- 在call的时候,an.party()没有输入参数,因此传入an,an.x的初始值为0,所以在第一次迭代的时候输出为1,此时x的值变为1,在第二、第三次迭代的时候便是基于这个基础上进行,所以后两行的输出为2和3.
在此基础上,我们可以继续探索我们新建的这个class的type以及dir,并同之前已学过的类比:
print('Type:' , type(an))
print('Dir:' , dir(an))
输出结果为:
Type: <class '__main__.PartyAnimal'>
Dir: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'party', 'x']
从dir的输出结果可以看出,除了前面一系列既定的,最后包含有method-party,以及attribute-x.
知识点6 Object life cycle
关于Object的寿命周期:
-
objects被创造、使用,最后废弃;
-
两类特殊的代码块,constructor(构造函数)和destructor,constructor在建立时使用,较常使用;destructor在废弃时使用,不常使用。
以下列代码为例:
class PartyAnimal:
x = 0
def __init__(self):
print('I am constructed')
def party(self):
self.x = self.x + 1
print('So far' , self.x)
def __del__(self):
print('I am destructed' , self.x)
an = PartyAnimal()
an.party()
an.party()
an = 42
print('an contains' , an)
代码的输出结果为:
I am constructed
So far 1
So far 2
I am destructed 2
an contains 42
constructor和destructor是可选择的,constructor的典型用法是来设定变量,destructor很少使用,如果使用,一般用于重新分配变量,或者程序结束。
解读:
- 我们可以创造许多的objects(因为objects是class的具象体现,class是object的模板)
- 我们可以存放不同的object在其自己的变量中
- 我们称这种情况为在相同的class中有多样的object
- 每一个object都有它自己的 instance variables的副本
一定要注意,构造函数__init__一共是四个下划线,__del__也是同理!
class PartyAnimal:
x = 0
name = ""
def __init__(self , z):
self.name = z
print(self.name , "constructed")
def party(self):
self.x = self.x + 1
print(self.name , "party count" , self.x)
s = PartyAnimal("Sally")
s.party()
j = PartyAnimal("Jim")
j.party()
s.party()
代码输出结果为:
Sally constructed
Sally party count 1
Jim constructed
Jim party count 1
Sally party count 2
对代码进行解读:
- 首先是关于构造函数,init(),上面说到,构造函数的典型用法是来设定变量的,在本例中,构造函数就被用来了设定变量
- 其次是关于class variable和instance variable,在这里,instance variable就是name,这个是可以通过构造函数设定的,不同的instance/object都有不同的instance variable
- 再次是class中的x,这就是class variable,因为从程序的角度看,它是属于模板的
- 这里有两个x,两个name,它们都分别被存储在两个独立的object当中
知识点7 继承(inheritance)
简述:当我们形成一个新的类的时候,我们可以重复使用一个已存在的类,继承这个已存在的类的所有功能,并加入一些我们自己的东西成为一个新的类;这是存储与重新利用的一种新形式;可以只编一次程序,但是使用许多次;新的类(Child)有母类(Parents)的所有功能,但是不仅限这些功能。subclass-子类
方便理解,可以有一个类比关系,例如母类是animal,子类可以有dog\cat\bird等。
一下用一段代码进行说明:
class PartyAnimal:
x = 0
name = ""
def __init__(self , nam):
self.name = nam
print(self.name , "constructed")
def party(self):
self.x = self.x + 1
print(self.name , "party count" , self.x)
class FootballFan(PartyAnimal):
points = 0
def touchdown(self):
self.points = self.points + 7
self.party()
print(self.name , "points" , self.points)
s = PartyAnimal("Sally")
s.party()
j = FootballFan("Jim")
j.party()
j.touchdown()
在该段程序当中:
-
FootballFan是一个包含PartyAnimal的类;
-
FootbalFan包括PartyAnimal的所有功能,并有拓展功能;
-
其扩展功能便是points = 0往下的那一部分;
-
定义了子类之后,母类同样也是可以使用的。
所以说如果要描述FootballFans有什么元素,它包括x和name和points三个instance variable,以及__init__()和Party()和touchdown()三个method。 -
可以看到在touchdown这个method中调用了party这个method,说明在一个method当中是可以调用其他的method的。
-
还是需要明确一下object的概念,所有的变量变换都是基于在这个Object当中的。