面向对象程序设计中的术语对象(Object)基本上可以看做数据(特性)以及由一系列可以存取、操作这些数据的方法所组成的集合。传统意义上的“程序=数据结构+算法”被封装”掩盖“并简化为“程序=对象+消息”。对象是类的实例,类的抽象则需要经过封装。封装可以让调用者不用关心对象是如何构建的而直接进行使用。

首先说明一下python编程规范:

#!/usr/bin/env python#coding=utf-8#编程规范,示例如下: class ClassName(object):       '''testdoc         #这里面是一些说明文档,该类的说明信息是可以被help看到的              example:       '''       #注释的写法,可以在后面,也可以在上一行,单行注释以#号开头       a= 100          #this is a number for a       #thisis a number for b       b= 200       c= ['a','b']   #or 分行写       d= {                                   #列表、字典等可以分行写,这样更加直观                     'key1':'v1',                     'key2':'v2',                     'key3':'v3'       }        def__init__(self,num,m):                   #初始化方法。如果不写,则是从基类继承              self.age= num              self.__money= m        deftest(self):              return100        def__eq__(self,other):                 #魔术方法              returnself.age == other.age        def__del__(self):   #析构函数,在整个类调用执行完后会执行              print'world' d = Hello(2,200)d2 = Hello(3,100) print d == d2         #会自动调用__eq__方法,返回比较结果 print dprint d2

书写规范一般从 说明文、初始化方法、单行或多行注释等

一、构造方法:

 

下面示例说明了构造方法和初始化方法的执行顺序:

#!/usr/bin/env python class Of(object):        def __new__(cls,*args,**kwargs):               #构造方法                print 'new'                return super(Of,cls).__new__(cls,*args,**kwargs)                #returnobject.__new__(cls,*args,**kwargs)        def __init__(self):                #初始化方法                print "init"        def test(self):                print 'hello' f = Of()

执行结果如下:

newinit

说明了类在实例化时会先执行构造方法,再去执行初始化方法

下面的示例说明了构造方法和初始化方法的区别:

#!/usr/bin/env python class Resource(object):                 #父类的定义       def __init__(self):                #初始化方法,为了说明这里直接输出名字                print 'call me resource init'        def __new__(cls,*args,**kwargs):               #构造方法,这里使用这种传参可以接受任何类型的参数                print "resource new"                returnobject.__new__(cls,*args,**kwargs)         #返回值为object基类的构造方法的返回值 class DockerResource(Resource):         #子类的定义,继承了Resource类       def __new__(cls,*args,**kwargs):               #重新构造自己的构造方法                print "call me dockerresource new"                returnResource.__new__(cls,*args,**kwargs)            #返回值为Resource父类的构造方法的返回值         def __init__(self):                #定义自己的初始化方法                print 'call docker resourceinit'        def test(self):                #定义test方法                print 'dosker resource test' r = DockerResource()                  #实例化DockerResource,并将返回值传递给rprint r                          #打印r,查看返回值是什么print type(r)                  #查看r的类型r.test()

输出结果如下:

call me docker resource new                #首先调用了DockerResource的构造方法resource new                                      #构造方法返回的是Resource的构造方法,所以会执行Resource父类构造方法的print "resource new"call docker resource init                      #然后会执行自己的初始化方法<__main__.DockerResource object at0x7fa1a3edcf90>             #r现在接受的是Resource父类的构造方法的返回值,所以会有object出现
                    #类型为自己DockerResourcedosker resource test                                   #调用自己的test方法

在类中,首先会执行自己的构造方法,如果没有就会从父类继承,然后会执行自己的初始化方法,没有还是会从父类中继承,接下来就可以正常调用自己的实例方法了

 

 

二、继承:

下面的示例说明了子类继承父类

#!/usr/bin/env python class Resource(object):                 #定义一个父类,继承于object基类        def __new__(cls,*args,**kwargs):        #构造方法                print 'class resource __new__'                obj =super(Resource,cls).__new__(cls,*args,**kwargs)            #利用super函数找到自己的父类,并将它的构造方法传递给obj                print obj.__class__        #打印obj的类型                return obj                     #返回值为obj        def __init__(self):                       #初始化方法                print "call me init forResource"        def test(self):                print "call me test forResource"        def create(self):                print "call me create forResource" class subResource(Resource):               #定义子类,继承Resource父类        def __init__(self):                #定义自己的初始化方法                print 'sub resource init'        def test(self):                print 'sub resource test' class Heat(object):                #定义一个Heat类,继承于基类object,是个新式类        def __new__(cls,*args,**kwargs):               #定义自己的构造方法                print "class __new__%s" % cls                returnobject.__new__(cls,*args,**kwargs)                #返回值为object基类的构造方法的返回值        def __init__(self):                #定义初始化方法                print 'heat init'  r = Heat()                     #实例化print rh = Resource()              #实例化print hf = subResource()          #实例化print f

执行结果如下:

class __new__ 
               #实例化Heat类,首先执行自己的构造方法和初始化方法,所以先输出构造方法的print语句heat init                        #执行了自己的初始化方法<__main__.Heat object at0x7f43349ac050>                     #r实例化后继承的是object基类,打印返回值class resource __new__                #实例化Resource类,首先执行自己的构造方法和初始化方法,所以先输出构造方法的print语句
         #打印父类构造方法的返回值的类名call me init for Resource                     #执行自己的初始化方法<__main__.Resource object at0x7f43349ac090>               # h实例化后继承的是object基类,打印返回值 class resource __new__                #实例化subResource类,首先执行父类的构造方法,所以先输出父类构造方法的print语句
           #父类构造方法里面打印自己的类名sub resource init                   #执行自己的初始化方法<__main__.subResource object at0x7f43349ac0d0>                 #f实例化后是执行了父类Resource类的构造方法,返回的依旧是object基类

三、多重继承:

#!/usr/bin/env python class A(object):       def __init__(self):               pass       def ma(self):                print 'a.ma'       def m(self):                print 'it is A'class B(object):       def mb(self):                print 'b.mb'       def m(self):                print 'it is B' class C(A,B):       pass c = C()c.ma()c.mb()c.m()

执行结果如下:

a.mab.mbit is A

通过执行结果,我们可以看出,C是继承了AB的,所以它可以调用Ama()方法,也可以调用Bmb()方法;但是当AB里面有相同的方法时,它会优先去执行继承的第一个超类。

四、继承和重载:

#!/usr/bin/env python class Phone(object):        def __init__(self,size,color,memory):                self.size = size                self.color = color                self.memory = memory        def call(self):                s = 'I can call'                return s       def sms(self):                s = 'Are you gua le mei?'#!/usr/bin/env python class Phone(object):        def __init__(self,size,color,memory):                self.size = size                self.color = color                self.memory = memory        def call(self):                s = 'I can call'                return s       def sms(self):                s = 'Are you gua le mei?'                return s class Phones(Phone):            #继承了Phone类,重载了自己的初始化方法,又增加了自己的方法,既拥有超类的方法,又有自己特有的方法        def __init__(self,size,color,memory,pix):                self.pix = pix               super(Phones,self).__init__(size,color,memory)        def install_app(self,app):                s = 'install %s' % app                return s class Huwei(Phone):                    #继承了Phone类,又增加了自己的方法,既拥有超类的方法,又有自己特有的方法        def weixin(self,msg):                if msg.find('gcd') == -1:                        return 'sending....'                else:                        return 'You can\'t sendthe msg' p = Phone(1.2,'black','4M')                  #实例化 iphone =Phones(4.7,'white','4G','1280*766')        #实例化 h = Huwei(4.7,'yellow','4G')                #实例化 print iphone.install_app('weixin')          #执行特有的install_app方法 print h.sms()print h.call()print h.weixin('wansui')sms = p.sms()call = p.call()print sms,call

执行结果如下:

install weixinAre you gua le mei?I can callsending....Are you gua le mei? I can call

方法的重载实际上就是在类中使用def关键字重载父类的方法。如果重载父类中的方法,但又需要

在类中使用父类的该方法,可以使用父类名加‘ .’加方法名的形式调用

五、魔术方法:

#!/usr/bin/env python class Information(object):       '''This is a doc                #说明文档                example for test,please don'tchange it.       '''        def __init__(self,sch,cla,m,n):             #定义初始化方法                print "welecome to schoolsystem."                self.school = sch                   #实例变量                self.cla***oom = cla                     #实例变量                self.num = 100                     #实例变量                self.__money = m                #私有变量                self.num = n                        #实例变量        def school_name(self):                 #返回实例变量,即将实例变量传递出去                return self.school        def class_name(self):                   #返回实例变量,即将实例变量传递出去                return self.cla***oom        def class_money(self):                 #返回私有变量,即将私有变量传递出去                return self.__money              #魔术方法:以双下划线开头,以双下划线结尾的方法是魔术方法       def __eq__(self,another):             #当外部出现'=='比较的时候,调用此魔术方法                return self.__money ==another.__money           #返回两个私有变量的比较结果(布尔值),这里self是'=='左边的参数值,another是右边的参数值        def __gt__(self,another):                     #当外部出现'>'比较的时候,调用此魔术方法                return self.__money >another.__money             #返回两个私有变量的比较结果(布尔值),这里self是'>'左边的参数值,another是右边的参数值        def __ne__(self,another):             #当外部出现'!='比较的时候,调用此魔术方法                return self.__money !=another.__money            #返回两个私有变量的比较结果(布尔值),这里self是'!='左边的参数值,another是右边的参数值        def __add__(self,another):            #当外部出现'+'运算符的时候,调用此魔术方法                return self.__money +another.__money      #返回两个私有变量的相加结果,这里self是'!='左边的参数值,another是右边的参数值                #returnInformation('jiaoda','dz1302',self.__money + another.__money)                #return Information('jiaoda','dz1302',1024,self.num+ another.num)        def __str__(self):                return 'money = %d' %self.__money        def __hash__(self):               #获取hash值                return 1314521        def __getattr__(self,name):                  #当调用不存在的方法时,执行此方法进行输出                print "get attr %s" %name                return name        def __del__(self):          #析构方法,当不再使用此类时,会自动执行                print "Goodbye,welecomhere again." f = Information('youdian','tg1312',9999,6)           #实例化l = Information('ligong','jk1213',6666,4)             #实例化print f == l            #调用魔术方法__eq__()print f + l                     #调用魔术方法__add__()print f > l                     #调用魔术方法__gt__() s = f + l                 #print sprint f.ccc              #名字不存在,调用__getatter__()方法

__str__是被print函数调用的,一般都是return一个什么东西。这个东西应该是以字符串的形式表现的。如果不是要用str()函数转换。当你打印一个类的时候,那么print首先调用的就是类里面的定义的__str__

 

执行结果如下:

welecome to school system.          #首先会在实例化的时候执行初始化方法welecome to school system.          #第二次实例化调用初始化方法False                     #打印__eq__()的返回值为False16665                   #打印__add__()的返回值为两数相加True                      #打印__gt__()的返回值为True16665get attr ccc             #执行__getattr__()方法cccGoodbye,welecom here again.             #执行完会自动执行析构函数Goodbye,welecom here again.

六、模块:

python中,自带200多个模块,现在经过大家的不断完善以及改进,官网已经收集了两千多库模块,几乎可以实现任何你想要的功能。

 

在我们自己使用时,也可以使用自己的模块,任何一个.py都可以作为一个单独的模块进行导入;

 

现在我们首先定义一个自己的模块:module.py

#!/usr/bin/env python#coding=utf-8 def test():       print'This is a test' def test2():       print'test2' class DB(object):       def__init__(self):              self.a= 101       deftest(self):              returnself.a

在同一目录下,打开python交互式就可以导入这个模块,名字就是文件的名module

在文件中写入进行导入调用,,,,,这里是在同一目录下(同一层)

#!/usr/bin/env python import modulemodule.test()

结果如下:

This is a test

改进一下,进行调用模块中的类:

#!/usr/bin/env python import moduleh = module.DB()print h.test()

输出结果如下:

101

下面我们试着去导入一个目录下的模块:

新建一个目录heat,在里面写入几个模块文件

目录下必须有__init__.py才能被当做模块导入

heat目录下的docker.py内容为:

#!/usr/bin/env python def docker():       return'This is a docker in heat' class Docker(object):       defcreate_c(self):              return'1314521aaa'        defstop_c(self):              return'it is stop' print __name__ if __name__ == '__main__':       print__name__       d= Docker()

heat目录下的nova.py内容为:

#!/usr/bin/env python def nova():       return'This is a nova' class Nova(object):       deftest(self):              return'This is a test in nova'

现在heat目录下只是有__init__这个文件,文件里面无内容

 

写一个调用的脚本文件:

#!/usr/bin/env python#coding=utf-8 import heat.docker               #目录下__init__.py里面没有__all__printheat.docker.docker()

执行结果如下:

heat.dockerThis is a docker in heatThis is a docker in heat

现在只能导入目录下的具体的模块,像上面一样导入和调用;

 

为了将目录下的所有模块文件都可以被导入,可以在目录下的__init__.py里面加下以下内容:

__all__ = ['docker','nova']                    #将所有模块名字写入

改变执行文件内容:

#!/usr/bin/env python#coding=utf-8 import heat.docker               #目录下__init__.py里面没有__all__print heat.docker.docker() from heat import *               #heat目录下__init__里面内容是:__all__ = ['docker',nova']print docker.docker()print nova.nova()n = nova.Nova()print n.test()

执行结果如下:

heat.dockerThis is a docker in heatThis is a docker in heatThis is a novaThis is a test in nova

如果在目录下还有目录里面存在需要导入的模块,可以继续在里面写__init__.py文件,并把目录下模块文件的名字写进去,在调用时多加一层目录就可以了。

下面示例一下里面mod.py文件内容:

#!/usr/bin/env python#coding=utf-8 def hello():       return'hello everyone' class Hello(object):       def__init__(self):              self.a= 103       deftest(self):              return'This is a test in Hello'

执行下面的脚本进行测试:

#!/usr/bin/env python#coding=utf-8 from heat.common import mod print mod.hello()h = mod.Hello()print h.test()

执行结果如下:

hello everyoneThis is a test in Hello

如果需要里面的所有模块文件,还是继续在__init__.py文件里写入就好了。

 

需要注意的是,文件被当做模块导入时,会产生.pyc文件,如果更改了模块,应该刷新.pyc文件,否则读取的还是旧信息。

 

为了防止文件是被作为模块使用的,我们应该在文件中加入

if __name__ == '__main__':       pass               #这里是要执行的语句

 

这样就可以防止当文件是被用作模块使用时,不会被执行if下面的语句,如果是当做程序来执行时,则会执行下面的语句,一般用作测试。