Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。
如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。
接下来我们先来简单的了解下面向对象的一些基本特征。
使用class语句来创建一个新类,class之后为类的名称并以冒号结尾:
classClassName:'类的帮助信息'#类文档字符串class_suite#类体类的帮助信息可以通过ClassName.__doc__查看。
class_suite由类成员,方法,数据属性组成。
以下是一个简单的Python类的例子:
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照惯例它的名称是self。
以上实例执行结果为:
<__main__.Testinstanceat0x10d066878>__main__.Test从执行结果可以很明显的看出,self代表的是类的实例,代表当前对象的地址,而self.__class__则指向类。
self不是python关键字,我们把他换成runoob也是可以正常执行的:
<__main__.Testinstanceat0x10d066878>__main__.Test创建实例对象实例化类其他编程语言中一般用关键字new,但是在Python中并没有这个关键字,类的实例化类似函数调用方式。
以下使用类的名称Employee来实例化,并通过__init__方法接收参数。
"创建Employee类的第一个对象"emp1=Employee("Zara",2000)"创建Employee类的第二个对象"emp2=Employee("Manni",5000)访问属性您可以使用点号.来访问对象的属性。使用如下类的名称访问类变量:
emp1.displayEmployee()emp2.displayEmployee()print"TotalEmployee%d"%Employee.empCount完整实例:
执行以上代码输出结果如下:
Name:Zara,Salary:2000Name:Manni,Salary:5000TotalEmployee2你可以添加,删除,修改类的属性,如下所示:
emp1.age=7#添加一个'age'属性emp1.age=8#修改'age'属性delemp1.age#删除'age'属性你也可以使用以下函数的方式来访问属性:
Python内置类属性调用实例如下:
Employee.__doc__:所有员工的基类Employee.__name__:EmployeeEmployee.__module__:__main__Employee.__bases__:()Employee.__dict__:{'__module__':'__main__','displayCount':
一个内部跟踪变量,称为一个引用计数器。
当对象被创建时,就创建了一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收。但是回收不是"立即"的,由解释器在适当的时机,将垃圾对象占用的内存空间回收。
a=40#创建对象<40>b=a#增加引用,<40>的计数c=[b]#增加引用.<40>的计数dela#减少引用<40>的计数b=100#减少引用<40>的计数c[0]=-1#减少引用<40>的计数垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充,垃圾收集器也会留心被分配的总量很大(即未通过引用计数销毁的那些)的对象。在这种情况下,解释器会暂停下来,试图清理所有未引用的循环。
析构函数__del__,__del__在对象销毁的时候被调用,当对象不再被使用时,__del__方法运行:
以上实例运行结果如下:
308340132430834013243083401324Point销毁注意:通常你需要在单独的文件中定义一个类,
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
继承语法class派生类名(基类名)...在python中继承中的一些特点:
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承"。
语法:
classSubClassName(ParentClass1[,ParentClass2,...]):...实例#!/usr/bin/python#-*-coding:UTF-8-*-classParent:#定义父类parentAttr=100def__init__(self):print"调用父类构造函数"defparentMethod(self):print'调用父类方法'defsetAttr(self,attr):Parent.parentAttr=attrdefgetAttr(self):print"父类属性:",Parent.parentAttrclassChild(Parent):#定义子类def__init__(self):print"调用子类构造方法"defchildMethod(self):print'调用子类方法'c=Child()#实例化子类c.childMethod()#调用子类的方法c.parentMethod()#调用父类方法c.setAttr(200)#再次调用父类的方法-设置属性值c.getAttr()#再次调用父类的方法-获取属性值以上代码执行结果如下:
调用子类构造方法调用子类方法调用父类方法父类属性:200你可以继承多个类
classA:#定义类A.....classB:#定义类B.....classC(A,B):#继承类A和B.....你可以使用issubclass()或者isinstance()方法来检测。
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法:
实例:
调用子类方法基础重载方法下表列出了一些通用的功能,你可以在自己的类重写:
Python同样支持运算符重载,实例如下:
以上代码执行结果如下所示:
在类的内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数
Python通过改变名称来包含类名:
122Traceback(mostrecentcalllast):File"test.py",line17,in
#!/usr/bin/python#-*-coding:UTF-8-*-classRunoob:__site="www.runoob.com"runoob=Runoob()printrunoob._Runoob__site