虽然Python是解释性语言,可是它是面向对象的,可以进行对象编程。下面就来了解一下如何在Python中进行对象编程。
类是对现实一类事物的封装
如何定义一个类:
class className:
block
注意类名后面有个冒号,在block块里面就能够定义属性和方法了。当一个类定义完以后,就产生了一个类对象。类对象支持两种操做:引用和实例化。引用操做是经过类对象去调用类中的属性或者方法,而实例化是产生出一个类对象的实例,称做实例对象。
好比定义一个People类:
class people:
name = 'jack' #定义了一个属性
#定义了一个方法
def printName(self):
print self.name
people类定义完成以后就产生了一个全局的类对象,能够经过类对象来访问类中的属性和方法了。当经过people.name(至于为何能够直接这样访问属性后面再解释,这里只要理解类对象这个概念就好了)来访问时,people.name中的people称为类对象,这点和C++中的有所不一样。固然还能够进行实例化操做,p=people( ),这样就产生了一个people的实例对象,此时也能够经过实例对象p来访问属性或者方法了(p.name).
理解了类、类对象和实例对象的区别以后,咱们来了解一下Python中属性、方法和函数的区别。
在上面代码中注释的很清楚了,name是一个属性,printName( )是一个方法,与某个对象进行绑定的函数称做为方法。通常在类里面定义的函数与类对象或者实例对象绑定了,因此称做为方法;而在类外定义的函数通常没有同对象进行绑定,就称为函数。
二.属性
在类中咱们能够定义一些属性,好比:
class people:
name = 'jack'
age = 12html
p = people()
print p.name,p.age
定义了一个people类,里面定义了name和age属性,默认值分别为'jack'和12。在定义了类以后,就能够用来产生实例化对象了,这句p = people( )实例化了一个对象p,而后就能够经过p来读取属性了。这里的name和age都是公有的,能够直接在类外经过对象名访问,若是想定义成私有的,则需在前面加2个下划线 ' __'。
class people:
__name = 'jack'
__age = 12python
p = people()
print p.__name,p.__age(会报错,私有属性只能在类的内部使用)
提示找不到该属性,由于私有属性是不可以在类外经过对象名来进行访问的。在Python中没有像C++中public和private这些关键字来区别公有属性和私有属性,它是以属性命名方式来区分,若是在属性名前面加了2个下划线'__',则代表该属性是私有属性,不然为公有属性(方法也是同样,方法名前面加了2个下划线的话表示该方法是私有的,不然为公有的)。
三.方法
在类中能够根据须要定义一些方法,定义方法采用def关键字,在类中定义的方法至少会有一个参数,,通常以名为'self'的变量做为该参数(用其余名称也能够),并且须要做为第一个参数。下面看个例子:
class Peopel:
__name='jack'
__age=10
def getName(self)
return self.__name
def getAge(self):
return self.__age
若是对self很差理解的话,能够把它当作C++中类里面的this指针同样理解,就是对象自身的意思,在用某个对象调用该方法时,就将该对象做为第一个参数传递给self。
五.类属性、实例属性、类方法、实例方法以及静态方法
在了解了类基本的东西以后,下面看一下python中这几个概念的区别。
先来谈一下类属性和实例属性
在前面的例子中咱们接触到的就是类属性,顾名思义,类属性就是类对象所拥有的属性,它被全部类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点相似。对于公有的类属性,在类外能够经过类对象和实例对象访问。
class people:
name = 'jack' #公有的类属性
__age = 12 #私有的类属性
p = people()
print p.name #正确
print people.name #正确
print p.__age #错误,不能在类外经过实例对象访问私有的类属性
print people.__age #错误,不能在类外经过类对象访问私有的类属性
在类外对类对象people进行实例化以后,产生了一个实例对象p,而后p.age = 12这句给p添加了一个实例属性age,赋值为12。这个实例属性是实例对象p所特有的,注意,类对象people并不拥有它(因此不能经过类对象来访问这个age属性)。固然还能够在实例化对象的时候给age赋值。
class people:
name = 'jack'
#__init__()是内置的构造方法,在实例化对象时自动调用
def __init__(self,age):
self.age = age编程
p = people(12)
print p.name #正确
print p.age #正确函数
print people.name #正确
print people.age #错误this
下面来看一下类方法、实例方法和静态方法的区别。
类方法:是类对象所拥有的方法,须要用修饰器"@classmethod"来标识其为类方法,对于类方法,第一个参数必须是类对象,通常以"cls"做为第一个参数(固然能够用其余名称的变量做为其第一个参数,可是大部分人都习惯以'cls'做为第一个参数的名字,就最好用'cls'了),可以经过实例对象和类对象去访问。
class people:
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country指针
p = people()
print p.getCountry() #能够用过实例对象引用
print people.getCountry() #能够经过类对象引用
类方法还有一个用途就是能够对类属性进行修改:
class people:
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country
@classmethod
def setCountry(cls,country):
cls.country = country
htm
p = people()
print p.getCountry() #能够用过实例对象引用
print people.getCountry() #能够经过类对象引用对象
p.setCountry('japan') blog
print p.getCountry()
print people.getCountry()
实例方法:在类中最常定义的成员方法,它至少有一个参数而且必须以实例对象做为其第一个参数,通常以名为'self'的变量做为第一个参数(固然能够以其余名称的变量做为第一个参数)。在类外实例方法只能经过实例对象去调用,不能经过其余方式去调用。
class people:
country = 'china'
#实例方法
def getCountry(self):
return self.country 继承
p = people()
print p.getCountry() #正确,能够用过实例对象引用
print people.getCountry() #错误,不能经过类对象引用实例方法
静态方法:须要经过修饰器"@staticmethod"来进行修饰,静态方法不须要多定义参数。
class people:
country = 'china'
@staticmethod
#静态方法
def getCountry():
return people.country
print people.getCountry()
对于类属性和实例属性,若是在类方法中引用某个属性,该属性一定是类属性,而若是在实例方法中引用某个属性(不做更改),而且存在同名的类属性,此时若实例对象有该名称的实例属性,则实例属性会屏蔽类属性,即引用的是实例属性,若实例对象没有该名称的实例属性,则引用的是类属性;若是在实例方法更改某个属性,而且存在同名的类属性,此时若实例对象有该名称的实例属性,则修改的是实例属性,若实例对象没有该名称的实例属性,则会建立一个同名称的实例属性。想要修改类属性,若是在类外,能够经过类对象修改,若是在类里面,只有在类方法中进行修改。
从类方法和实例方法以及静态方法的定义形式就能够看出来,类方法的第一个参数是类对象cls,那么经过cls引用的一定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么经过self引用的多是类属性、也有多是实例属性(这个须要具体分析),不过在存在相同名称的类属性和实例属性的状况下,实例属性优先级更高。静态方法中不须要额外定义参数,所以在静态方法中引用类属性的话,必须经过类对象来引用。
内置方法 说明
__init__(self,...) 初始化对象,在建立新对象时调用
__del__(self) 释放对象,在对象被删除以前调用
__new__(cls,*args,**kwd) 实例的生成操做
__str__(self) 在使用print语句时被调用
__getitem__(self,key) 获取序列的索引key对应的值,等价于seq[key]
__len__(self) 在调用内联函数len()时被调用
__cmp__(stc,dst) 比较两个对象src和dst
__getattr__(s,name) 获取属性的值
__setattr__(s,name,value) 设置属性的值
__delattr__(s,name) 删除name属性
__getattribute__() __getattribute__()功能与__getattr__()相似
__gt__(self,other) 判断self对象是否大于other对象
__lt__(slef,other) 判断self对象是否小于other对象
__ge__(slef,other) 判断self对象是否大于或者等于other对象
__le__(slef,other) 判断self对象是否小于或者等于other对象
__eq__(slef,other) 判断self对象是否等于other对象
__call__(self,*args) 把实例对象做为函数调用
http://www.cnblogs.com/simayixin/archive/2011/05/04/2036295.html
一.继承和多继承
在Python中类的继承定义基本形式以下:
#父类
class superClassName:
block
#子类
class subClassName(superClassName):
block
在定义一个类的时候,能够在类名后面紧跟一对括号,在括号中指定所继承的父类,若是有多个父类,多个父类名之间用逗号隔开。以大学里的学生和老师举例,能够定义一个父类UniversityMember,而后类Student和类Teacher分别继承类UniversityMember:
class UniversityMember:
def __init__(self,name,age):
self.name = name
self.age = age
def getName(self):
return self.name
def getAge(self):
return self.age
class Student(UniversityMember):
def __init__(self,name,age,sno,mark):
UniversityMember.__init__(self,name,age) #注意要显示调用父类构造方法,并传递参数self
self.sno = sno
self.mark = mark
def getSno(self):
return self.sno
def getMark(self):
return self.mark
class Teacher(UniversityMember):
def __init__(self,name,age,tno,salary):
UniversityMember.__init__(self,name,age)
self.tno = tno
self.salary = salary
def getTno(self):
return self.tno
def getSalary(self):
return self.salary
在大学中的每一个成员都有姓名和年龄,而学生有学号和分数这2个属性,老师有教工号和工资这2个属性,从上面的代码中能够看到:
1)在Python中,若是父类和子类都从新定义了构造方法__init( )__,在进行子类实例化的时候,子类的构造方法不会自动调用父类的构造方法,必须在子类中显示调用。
2)若是须要在子类中调用父类的方法,须要以 父类名.方法 这种方式调用,以这种方式调用的时候,注意要传递self参数过去。
对于继承关系,子类继承了父类全部的公有属性和方法,能够在子类中经过父类名来调用,而对于私有的属性和方法,子类是不进行继承的,所以在子类中是没法经过父类名来访问的。
对于多重继承,好比
class SubClass(SuperClass1,SuperClass2)
此时有一个问题就是若是SubClass没有从新定义构造方法,它会自动调用哪一个父类的构造方法?这里记住一点:以第一个父类为中心。若是SubClass从新定义了构造方法,须要显示去调用父类的构造方法,此时调用哪一个父类的构造方法由你本身决定;若SubClass没有从新定义构造方法,则只会执行第一个父类的构造方法。而且若SuperClass1和SuperClass2中有同名的方法,经过子类的实例化对象去调用该方法时调用的是第一个父类中的方法。