一、引言
所有的程序都是由“数据”与“功能”组成,“数据”很好理解,比如学生的名字,学生的性别,程序的“功能”是一系列动态的操作,比如查看学生的名字,查看学生的性别。在面向对象这个概念出来之前,我们的程序是基于过程的,也就是面向过程编程,如下
# 数据:name、age、sex
name='lili'
age=18
sex='female'
# 功能:tell_info
def tell_info(name,age,sex):
print('<%s:%s:%s>' %(name,age,sex))
# 此时若想执行查看个人信息的功能,需要同时拿来两样东西,一类是功能tell_info,另外一类则是多个数据name、age、sex,然后才能执行,非常麻烦
tell_info(name,age,sex)
我们可以看到,“数据”和“功能”是分散的,在拓展后续代码的时候很容易混乱,不易拓展。
面向对象的核心是“对象”二字,对象就像一个容器,把数据和功能两个属性封装起来,这是一种“整合”的思想。面向对象的程序设计把程度变成一个一个对象,整合度高,拓展性好!
二、类与对象
类即类别/种类,是面向对象分析和设计的基石,如果多个对象有相似的数据与功能,那么该多个对象就属于同一种类。有了类的好处是:我们可以把同一类对象相同的数据与功能存放到类里,而无需每个对象都重复存一份,这样每个对象里只需存自己独有的数据即可,极大地节省了空间。所以,如果说对象是用来存放数据与功能的容器,那么类则是用来存放多个对象相同的数据与功能的容器。
三、面向对象编程
3.1类的定义与实例化
class Student:
school='BD'
#该方法会在对象产生之后自动执行,专门为对象进行初始化操作,可以有任意代码,但一定不能返回非None的值
def __init__(self,name,sex,age):
self.name=name
self.sex=sex
self.age=age
def choose(self):
print('%s is choosing a course' %self.name)
上面的代码有一点需要注意:
1.我们看一下类:Student的名称空间(为什么变量开辟了内存)
也就是说,程序在类定义的时候就会分配名称空间。
我们再来看一下实例化之后,对象的命名空间,只有修改的部分为单独开辟内存,没修改的部分还是调用(指向)原来的类。
2.不同对象的相同数据属性,在类中是一样的,是指向操作,如果对象不单独修改,不会改变地址。但是类的函数方法是绑定给对象的,虽然对象没有修改函数方法,但是,每个对象相同的函数都是不同的地址。
3.2属性访问
>>> Student.school # 访问数据属性,等同于Student.__dict__['school']
>>> Student.choose # 访问函数属性,等同于Student.__dict__['choose']
<function Student.choose at 0x1018a2123>
# 除了查看属性外,我们还可以使用Student.attrib=value(修改或新增属性),用del Student.attrib删除属性。
>>> stu1.name # 查看,等同于obj1.__dict__[‘name']
'李建刚'
>>> stu1.course=’python’ # 新增,等同于obj1.__dict__[‘course']='python'
>>> stu1.age=38 # 修改,等同于obj1.__dict__[‘age']=38
>>> del obj1.course # 删除,等同于del obj1.__dict__['course']
3.3属性查找顺序与绑定方法
对象的名称空间里只存放着对象独有的属性,而对象们相似的属性是存放于类中的。对象在访问属性时,会优先从对象本身的_dict_中查找,未找到,则去类的_dict_中查找
注意:
我们在使用super()调用父类或者初始化父类的时候,我们是按照mro的顺序初始化的;多继承的时候,对象调用的时候也是参考的mro(广度优先)
3.4一切皆对象
#类型list就是类
>>> list
<class 'list'>
#实例化的到3个对象l1,l2,l3
>>> l1=list([1,2,3])
>>> l2=list(['a','b','c'])
>>> l3=list(['x','y'])
#三个对象都有绑定方法append,是相同的功能,但内存地址不同
>>> l1.append
<built-in method append of list object at 0x10b482b48>
>>> l2.append
<built-in method append of list object at 0x10b482b88>
>>> l3.append
<built-in method append of list object at 0x10b482bc8>
#操作绑定方法l1.append(4),就是在往l1添加4,绝对不会将4添加到l2或l3
>>> l1.append(4) #等同于list.append(l1,4)
>>> l1
[1,2,3,4]
>>> l2
['a','b','c']
>>> l3
['x','y']