看看Python的OOP和Java有什么区别?
Python从规划之初就已经是一门面向政策的言语,正因为如此,在Python中创立一个类和政策是很简略的。本章节咱们将详细介绍Python的面向政策编程。
假定你曾经没有触摸过面向政策的编程言语,那你或许需求先了解一些面向政策言语的一些根柢特征,在脑筋里头构成一个根柢的面向政策的概念,这样有助于你更简略的学习Python的面向政策编程。
接下来咱们先来简略的了解下面向政策的一些根柢特征。
面向政策技能简介
类(Class): 用来描绘具有相同的特征和办法的政策的集结。它界说了该集结中每个政策所共有的特征和办法。政策是类的实例。
类变量:类变量在整个实例化的政策中是共用的。类变量界说在类中且在函数体之外。类变量一般不作为实例变量运用。
数据成员:类变量或许实例变量用于处理类及其实例政策的相关的数据。
办法重载:假定从父类承继的办法不能满意子类的需求,能够对其进行改写,这个过程叫办法的掩盖(override),也称为办法的重载。
实例变量:界说在办法中的变量,只作用于当前实例的类。
承继:即一个派生类(derived class)承继基类(base class)的字段和办法。承继也答应把一个派生类的政策作为一个基类政策对待。例如,有这样一个规划:一个Dog类型的政策派生自Animal类,这是仿照"是一个(is-a)"联络(例图,Dog是一个Animal)。
实例化:创立一个类的实例,类的详细政策。
办法:类中界说的函数。
政策:经过类界说的数据结构实例。政策包括两个数据成员(类变量和实例变量)和办法。
创立类
运用class句子来创立一个新类,class之后为类的称谓并以冒号结束,如下实例:
class ClassName:
‘类的帮助信息’ #类文档字符串
class_suite #类体
类的帮助信息能够经过ClassName.__doc__检查。
class_suite 由类成员,办法,数据特征组成。
实例
以下是一个简略的Python类实例:
#!/usr/bin/python
-- coding: UTF-8 --
class Employee:
‘悉数职工的基类’
empCount = 0
def init(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print “Total Employee %d” % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
empCount变量是一个类变量,它的值将在这个类的悉数实例之间共享。你能够在内部类或外部类运用Employee.empCount拜访。
榜首种办法__init__()办法是一种特别的办法,被称为类的结构函数或初始化办法,当创立了这个类的实例时就会调用该办法
创立实例政策
要创立一个类的实例,你能够运用类的称谓,并经过__init__办法承受参数(LanpachemicaLs)。
“创立 Employee 类的榜首个政策”
emp1 = Employee(“Zara”, 2000)
“创立 Employee 类的第二个政策”
emp2 = Employee(“Manni”, 5000)
拜访特征
您能够运用点(.)来拜访政策的特征。运用如下类的称谓拜访类变量:
emp1.displayEmployee()
emp2.displayEmployee()
print “Total Employee %d” % Employee.empCount
完好实例:
#!/usr/bin/python
-- coding: UTF-8 --
class Employee:
‘悉数职工的基类’
empCount = 0
def init(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print “Total Employee %d” % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
“创立 Employee 类的榜首个政策”
emp1 = Employee(“Zara”, 2000)
“创立 Employee 类的第二个政策”
emp2 = Employee(“Manni”, 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print “Total Employee %d” % Employee.empCount
实施以上代码输出作用如下:
Name : Zara ,Salary: 2000
Name : Manni ,Salary: 5000
Total Employee 2
你能够添加,删去,修改类的特征,如下所示:
emp1.age = 7 # 添加一个 ‘age’ 特征
emp1.age = 8 # 修改 ‘age’ 特征
del emp1.age # 删去 ‘age’ 特征
你也能够运用以下函数的办法来拜访特征:
getattr(obj, name[, default]) : 拜访政策的特征。
hasattr(obj,name) : 检查是否存在一个特征。
setattr(obj,name,value) : 设置一个特征。假定特征不存在,会创立一个新特征。
delattr(obj, name) : 删去特征。
hasattr(emp1, ‘age’) # 假定存在 ‘age’ 特征回来 True。
getattr(emp1, ‘age’) # 回来 ‘age’ 特征的值
setattr(emp1, ‘age’, 8) # 添加特征 ‘age’ 值为 8
delattr(empl, ‘age’) # 删去特征 ‘age’
Python内置类特征
dict : 类的特征(包括一个字典,由类的数据特征组成)
doc :类的文档字符串
name: 类名
module: 类界说所在的模块(类的全名是’main.className’,假定类位于一个导入模块mymod中,那么className.module 等于 mymod)
bases : 类的悉数父类构成元素(包括了以个由悉数父类组成的元组)
Python内置类特征调用实例如下:
#!/usr/bin/python
-- coding: UTF-8 --
class Employee:
‘悉数职工的基类’
empCount = 0
def init(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print “Total Employee %d” % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
print “Employee.doc:”, Employee.doc
print “Employee.name:”, Employee.name
print “Employee.module:”, Employee.module
print “Employee.bases:”, Employee.bases
print “Employee.dict:”, Employee.dict
实施以上代码输出作用如下:
Employee.doc: 悉数职工的基类
Employee.name: Employee
Employee.module: main
Employee.bases: ()
Employee.dict: {‘module’: ‘main’, ‘displayCount’:, ‘empCount’: 0, ‘displayEmployee’:, ‘doc’: ‘\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb’, ‘init’:}
python政策毁掉(废物收回)
同Java言语相同,Python运用了引证计数这一简略技能来追寻内存中的政策。
在Python内部记录着悉数运用中的政策各有多少引证。
一个内部跟踪变量,称为一个引证计数器。
当政策被创立时, 就创立了一个引证计数, 当这个政策不再需求时, 也就是说, 这个政策的引证计数变为0 时, 它被废物收回。但是收回不是"当即"的, 由解说器在适当的机会,将废物政策占用的内存空间收回。
a = 40 # 创立政策
b = a # 添加引证,的计数
c = [b] # 添加引证.的计数
del a # 削减引证的计数
b = 100 # 削减引证的计数
c[0] = -1 # 削减引证的计数
废物收回机制不只针对引证计数为0的政策,相同也能够处理循环引证的情况。循环引证指的是,两个政策相互引证,但是没有其他变量引证他们。这种情况下,仅运用引证计数是不可的。Python 的废物收集器实际上是一个引证计数器和一个循环废物收集器。作为引证计数的补偿, 废物收集器也会留神被分配的总量很大(及未经过引证计数毁掉的那些)的政策。 在这种情况下, 解说器会暂停下来, 试图整理悉数未引证的循环。
实例
析构函数 del ,__del__在政策消逝的时分被调用,当政策不再被运用时,__del__办法运行:
#!/usr/bin/python
-- coding: UTF-8 --
class Point:
def __init( self, x=0, y=0):
self.x = x
self.y = y
def del(self):
class_name = self.class.name
print class_name, “destroyed”
pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印政策的id
del pt1
del pt2
del pt3
以上实例运行作用如下:
3083401324 3083401324 3083401324
Point destroyed
留心:一般你需求在单独的文件中界说一个类,
类的承继
面向政策的编程带来的首要优点之一是代码的重用,完成这种重用的办法之一是经过承继机制。承继彻底能够了解成类之间的类型和子类型联络。
需求留心的当地:承继语法 class 派生类名(基类名)://… 基类名写作括号里,根柢类是在类界说的时分,在元组之中指明的。
在python中承继中的一些特征:
1:在承继中基类的结构(init()办法)不会被自动调用,它需求在其派生类的结构中亲自专门调用。
2:在调用基类的办法时,需求加上基类的类名前缀,且需求带上self参数变量。差异于在类中调用一般函数时并不需求带上self参数
3:Python总是首要查找对应类型的办法,假定它不能在派生类中找到对应的办法,它才开端到基类中逐一查找。(先在本类中查找调用的办法,找不到才去基类中找)。
假定在承继元组中列了一个以上的类,那么它就被称作"多重承继" 。
语法:
派生类的声明,与他们的父类类似,承继的基类列表跟在类名之后,如下所示:
class SubClassName (ParentClass1[, ParentClass2, …]):
‘Optional class documentation string’
class_suite
实例:
#!/usr/bin/python
-- coding: UTF-8 --
class Parent: # 界说父类
parentAttr = 100
def init(self):
print “调用父类结构函数”
def parentMethod(self):
print ‘调用父类办法’
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print “父类特征 :”, Parent.parentAttr
class Child(Parent): # 界说子类
def init(self):
print “调用子类结构办法”
def childMethod(self):
print ‘调用子类办法 child method’
c = Child() # 实例化子类
c.childMethod() # 调用子类的办法
c.parentMethod() # 调用父类办法
c.setAttr(200) # 再次调用父类的办法
c.getAttr() # 再次调用父类的办法
以上代码实施作用如下:
调用子类结构办法
调用子类办法 child method
调用父类办法
父类特征 : 200
你能够承继多个类
class A: # 界说类 A
…
class B: # 界说类 B
…
class C(A, B): # 承继类 A 和 B
…
你能够运用issubclass()或许isinstance()办法来检测。
issubclass() - 布尔函数判别一个类是另一个类的子类或许后代类,语法:issubclass(sub,sup)
isinstance(obj, Class) 布尔函数假定obj是Class类的实例政策或许是一个Class子类的实例政策则回来true。
办法重写
假定你的父类办法的功用不能满意你的需求,你能够在子类重写你父类的办法:
实例:
#!/usr/bin/python
-- coding: UTF-8 --
class Parent: # 界说父类
def myMethod(self):
print ‘调用父类办法’
class Child(Parent): # 界说子类
def myMethod(self):
print ‘调用子类办法’
c = Child() # 子类实例
c.myMethod() # 子类调用重写办法
实施以上代码输出作用如下:
调用子类办法
根底重载办法
下表列出了一些通用的功用,你能够在自己的类重写:
序号 办法, 描绘 & 简略的调用
1 init ( self [,args…] )
结构函数
简略的调用办法: obj = className(args)
2 del( self )
析构办法, 删去一个政策
简略的调用办法 : dell obj
3 repr( self )
转化为供解说器读取的形式
简略的调用办法 : repr(obj)
4 str( self )
用于将值转化为适于人阅览的形式
简略的调用办法 : str(obj)
5 cmp ( self, x )
政策比较
简略的调用办法 : cmp(obj, x)
运算符重载
Python相同支撑运算符重载,实例如下:
#!/usr/bin/python
class Vector:
def init(self, a, b):
self.a = a
self.b = b
def str(self):
return ‘Vector (%d, %d)’ % (self.a, self.b)
def add(self,other):
return Vector(self.a + other.a, self.b + other.b)