python中面向对象
一、Python经典类与新类
经典类:如果没有直接或间接的子类化一个对象,也就是说如果没有指定一个父类,或者是如果子类化的基本类没有父类,那么就定义了经典类:
class classics: ‘define a classics Class‘ pass
新式类:与经典类相反。object是“所有类之母”,也就是基类,如果你的类没有继承任何父类,object将作为默认的父类:
class newClass(object): ‘define a classics Class‘ pass
二、Python的实例化
创建一个实例的过程叫实例化,在其他编程语言中一般用关键字 new ,但是在Python中没有这个关键字。而是类似函数调用的方式创建实例的:
class newClass(object): pass inst = newClass() print inst #<__main__.newClass object at 0x00B71650>
三、类最简单的用法
类最简单的用法仅仅用作名称空间,意味着将数据保存到变量中,使用句点属性标识对它们按名称空间分组。
class newClass(object): pass bar = newClass() #创建实例 bar.x = 1 #创建实例属性 bar.y = 2 print bar.x+bar.y
注意:bar.x ,bar.y 是实例对象的属性不是类的属性。
四、方法
方法就是类的功能
方法在类中定义,只能被实例调用。
在类中,方法有一个默认参数self,这个参数代表实例本身,当用实例调用方法时,由解释器悄悄传递给方法。
class newClass(object): def method(self): return self bar = newClass() print bar.method() #<__main__.newClass object at 0x00B71910>
在其他语言中,self一般称为this,一般方法会用到这个实例(self),但是静态方法和类方法不需要。
五、创建类、方法、实例对象访问
class addPerson(object): def __init__(self,nm,ph): #定义构造器 self.name = nm #设置name self.phone = ph #设置phone print ‘Created instance for‘,self.name def updatePhone(self,newph): self.phone = newph print ‘Updated phone for‘,self.phone josn = addPerson(‘JSON‘,‘1565208444‘) #创建实例对象josn ben = addPerson(‘Ben‘,‘15249638892‘) #创建实例对象ben print ‘Instance property:[%s][%s]‘ %(ben.name,ben.phone) #访问实例属性 ben.updatePhone(‘110‘) print ben.phone
六、子类
创建子类:靠继承来进行子类化,在不影响父类(基类)的基础上改进自己的功能。
如:继承上面的类
class addInfo(addPerson): def __init__(self,nm,ph,id,em): #定义自己的构造器 addPerson.__init__(self, nm, ph) #继承父类构造器(这个很重要) self.empid = id self.email = em def updateEmail(self,newem): self.email = newem print ‘Updated e-mail address for:‘,self.name zhangsan = addInfo(‘ZhangSan‘,‘123456789‘,‘01‘,‘‘) #创建addInfo实例,输出Created instance for ZhangSan print zhangsan #<__main__.addInfo object at 0x00B71BD0> print ‘Instance property:[%s],[%s],[%s],[%s]‘ %(zhangsan.name,zhangsan.phone,zhangsan.empid,zhangsan.email) #输出:Instance property:[ZhangSan],[123456789],[01],[] zhangsan.updatePhone(‘250‘) #Updated phone for 250 zhangsan.updateEmail(‘‘) #Updated e-mail address for: ZhangSan
注意:
如果需要,每个子类最好定义自己的构造器,不然的话,基类的构造器将会被调用。然而如果子类重写基类的构造器,那么基类的构造器就不会被自动调用,必须显式写出来才行,如上的:addPerson.__init__
一、类
类就是一个数据结构,封装了数据和操作。
类的声明与函数的声明十分类似:
class newClass(object): """class documentation string"""#类文档字符串 class_suite #类体
注意:类是对象(在Python中,一切皆对象),但是类在定义的时候,还不是对象的实现。
二、类属性
在面向对象的编程和思想中,出现了类属性的概念。在C++中,类属性是描述类的所有对象共同特征的一个数据项,对于任何对象实例,它的属性值是相同的。不同的编程语言有不同的定义。而有些语言是不区分static类型的,所以并不能用static来表示这个属性是否为类属性。只不过用static修饰的属性可以实现对象间的数据共享而已。
在Python中一个有趣的现象是:当访问一个属性时,它同时也是一个对象。拥有它自己的属性可以访问,这就造成了一个属性链。
1、类的数据属性:
就是定义类的变量,即静态变量,或静态数据。它们与所属的类对象绑定,不依赖任何类实例。这里类型的数据相当于在变量前面加上static。
class newClass(object): foo = 100 print newClass.foo #100 newClass.foo+=100 print newClass.foo #200
类属性与实例属性不一样。
2、方法
方法也成为类属性。
3、查看类属性
使用内建函数dir()或类的字典属性__dict__都可以。
class newClass(object): def foo(self): pass print dir(newClass) #[‘__class__‘, ‘__delattr__‘, ‘__dict__‘, ‘__doc__‘, ‘__getattribute__‘, ‘__hash__‘, ‘__init__‘, ‘__module__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__str__‘, ‘__weakref__‘, ‘foo‘] print newClass.__dict__ #{‘__dict__‘: <attribute ‘__dict__‘ of ‘newClass‘ objects>, ‘__module__‘: ‘__main__‘, ‘foo‘: <function foo at 0x00B00A30>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘newClass‘ objects>, ‘__doc__‘: None}
class newClass(object): """Python Class""" def foo(self): pass print newClass.__name__ #newClass print newClass.__doc__ #Python Class print newClass.__bases__ #(<type ‘object‘>,) print newClass.__base__ #<type ‘object‘> print newClass.__module__ #__main__ print newClass.__class__ #<type ‘type‘>
三、实例
1、关于类的实例
类是一种数据结构定义类型,那么实例就是声明这种类型的变量。
class newClass(object): """Python Class""" def foo(self): pass c = newClass() print type(c) #<class ‘__main__.newClass‘>,而在Python2.2版本之前,实例是”实例类型“从不考虑从哪个类来的 print type(0) #<type ‘int‘> print type(newClass) #<type ‘type‘> print type(int) #<type ‘type‘>两者都是类型
注意,在2.2版本之后,当定义一个新式类后,你已创建一个新的类型。
2、__init__() “构造器”方法
不通过new来创建实例,你也没有定义一个构造器,是Python为你创建对象
__init__()是在解释器为你创建一个实例后调用的第一个方法
如果没有定义(或覆盖)特殊方法__init__().则对实例不会施加任何特殊的操作。
3、__new__()“构造器”方法
与__init__()相比,__new__()则更像一个真正的构造器。
4、__del__()"解构器"方法
四、类属性与实例属性
参考:http://www.pythonfan.org/thread-9827-1-1.html
python中的类属性只是存储与类相关 的数据,和该类的实例无关。类属性和java中的静态成员变量类似。访问python的类属性可使用类名+“.”+属性名的方式,如果类的实例没有同名变 量也可以使用实例来访问。如果实例含有与类属性同名的属性,则用该实例访问属性时,访问的是实例中的属性。
class Test(): myVersion="1.0" #声明一个类属性,并赋值为1.0 t=Test() #生成一个实例 Test.myVersion #使用类空间来访问类属性 ,输出为 1.0 t.myVersion #使用实例空间来访问类属性,输出为1.0 Test.myVersion="2.0" #使用类空间来更新类属性 Test.myVersion #使用类空间来访问类属性 ,输出为 2.0 t.myVersion #使用实例空间来访问类属性,输出为2.0
只有使用类空间引用类属性时,才能设定和更新类属性。如果尝试使用实例空间来引用类属性来进行更新,则该实例(如果没有同名属性的话)会创建一个与该类属性同名的实例属性。该实例属性会阻止实例对类属性的访问,直到该实例的同名属性被清除掉。
t.myVersion=‘3.0‘ #实例t会创建一名为‘myVersion’的实例属性 Test.myVersion #输出2.0,上一条语句并不会对类属性产生任何影响 t.myVersion #输出3.0,t访问的是自身的实例属性 del t.myVersion #清除t的实例属性 t.myVersion #输出2.0,此时访问的是类属性
但是,在类属性可变的情况下,事情又不一样了
Test.x={‘myVersion‘:‘1.0‘} #给Test类添加一个新的类属性 Test.x #用类空间访问该属性 输出 {‘myVersion‘:‘1.0‘} t.x #用实例空间访问该属性 输出 {‘myVersion‘:‘1.0‘} t.x[‘myVersion‘]=‘2.0‘ t.x #输出{‘myVersion‘:‘2.0‘} Test.x #输出{‘myVersion‘:‘2.0‘} # 实例t的更新操作对类属性生效了 del t.x #出错 :t instance has no attribute ‘x‘