面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向对象与面向过程的区别
之前的面向过程的程序设计是把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
面向对象的设计思想更为自然,但其抽象程度要高于函数,另外,还有其三大特点:数据封装、继承和多态。
类和实例
类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
1 | class student(object): |
class
后跟类名,object
指的是继承的类,如果没有合适的类,就用object类,所有类都会最终继承它。__init__
方法第一个参数是self
,表示创建的实例本身,并且调用的时候,不用传递该参数。其他和普通函数没有什么区别。从而实现了对数据的封装。
好处其一:方便调用,不需要知道内部实现细节;
其二:可以给类增加新的方法。
访问限制
如果要让内部属性不被外部访问,可以把属性的名称前面加两个下划线,在Python
中,这样就成了私有变量,只有内部可以访问。
如果希望在外部进行访问和修改,可以增加get_name
和set_name
这样的方法:1
2
3
4
5def get_name(self):
return self.__name
def set_name(self):
self.__name = name
需要注意的是,变量名是以双下划线开头,并且双下划线结尾的是特殊变量,特殊变量是可以直接访问的。
另外,变量名以一个下划线开头的,这样的实例变量其实可以外部访问,但按照约定俗称的规定,看到这样的变量时,应该讲他看做私有变量,不要随意访问。
双划线开头的实例变量不是一定不能访问,不能直接访问·__name
是因为Python解释器对外把__name
变量改成了_Student__name
,所以,仍然可以通过_Student__name
来访问__name
变量。
但是强烈建议不能这么干,不同版本的Python解释器可能会把__name
改为不同的变量名。
继承和多态
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写;
有了继承,才能有多态。在调用类实例方法的时候,尽量把变量视作父类类型,这样,所有子类类型都可以正常被接收;
获取对象信息
当我们拿到一个对象的引用时,如道这个对象是什么类型?有什么方法呢?
type()
基本类型都可以用type()函数来判断。
另外,有一种类型就叫TypeType
,所有类型本身的类型就是TypeType
。
1 | type(123) |
isinstance()
对于class的继承关系,使用type()
就很不方便。我们要判断class
的类型,可以使用isinistance()
函数。
dir()
使用dir()函数可以获得一个对象的所有属性和方法。类似__xxx__
的属性和方法在Python中都是有特殊用途的,比如__len__
方法返回长度。在Python中,如果你调用len()
函数试图获取一个对象的长度,实际上,在len()
函数内部,它自动去调用该对象的__len__()
方法。
因此,我们自己写的类,如果也想用len(myObj)
的话,就自己写一个__len__()
方法。
操作对象的状态
我们可以通过getattr()
、setattr()
以及hasattr()
来操作对象的属性(attribute)。
1 | #getattr() 得到属性值 |
此python学习路径来源于廖雪峰的Python教程的一个学习内容的总结。以便于自己后的学习和整理。