物件導向程式設計中的術語物件(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 d print 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()
執行結果如下:
new init
說明了類別在實例化時會先執行建構方法,再去執行初始化方法
下面的範例說明了建構方法和初始化方法的差異:
#!/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,并将返回值传递给r print 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出现 <class '__main__.DockerResource'> #类型为自己DockerResource dosker 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 r h = Resource() #实例化 print h f = subResource() #实例化 print f
執行結果如下:
class __new__ <class '__main__.Heat'> #实例化Heat类,首先执行自己的构造方法和初始化方法,所以先输出构造方法的print语句 heat init #执行了自己的初始化方法 <__main__.Heat object at0x7f43349ac050> #r实例化后继承的是object基类,打印返回值 class resource __new__ #实例化Resource类,首先执行自己的构造方法和初始化方法,所以先输出构造方法的print语句 <class '__main__.Resource'> #打印父类构造方法的返回值的类名 call me init for Resource #执行自己的初始化方法 <__main__.Resource object at0x7f43349ac090> # h实例化后继承的是object基类,打印返回值 class resource __new__ #实例化subResource类,首先执行父类的构造方法,所以先输出父类构造方法的print语句 <class '__main__.subResource'> #父类构造方法里面打印自己的类名 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.ma b.mb it is A
四、繼承與重載:
#!/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 weixin Are you gua le mei? I can call sending.... Are you gua le mei? I can call
在類別中使用父類別的該方法,可以使用父類別名稱加' .'加方法名稱的形式呼叫
五、魔術方法:
#!/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.classroom = cla #实例变量 self.num = 100 #实例变量 self.__money = m #私有变量 self.num = n #实例变量 def school_name(self): #返回实例变量,即将实例变量传递出去 return self.school def class_name(self): #返回实例变量,即将实例变量传递出去 return self.classroom 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 s print f.ccc #名字不存在,调用__getatter__()方法
__str__是被print函數呼叫的,一般都是return一個什麼東西。這個東西應該是以字串的形式表現出來的。如果不是要用str()函數轉換。當你印出一個類別的時候,那麼print首先呼叫的就是類別裡面的定義的__str__
執行結果如下:
welecome to school system. #首先会在实例化的时候执行初始化方法 welecome to school system. #第二次实例化调用初始化方法 False #打印__eq__()的返回值为False 16665 #打印__add__()的返回值为两数相加 True #打印__gt__()的返回值为True 16665 get attr ccc #执行__getattr__()方法 ccc Goodbye,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
在檔案中寫入進行導入調用,,,,這裡是在同一目錄下(同一層)
#!/usr/bin/env python import module module.test()
This is a test
##
#!/usr/bin/env python import module h = module.DB() print h.test()
101
目錄下必須有__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.docker This is a docker in heat This 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.docker This is a docker in heat This is a docker in heat This is a nova This is a test in nova
下面範例裡面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 everyone This is a test in Hello
如果需要裡面的所有模組文件,還是繼續在__init__.py檔案裡寫入就好了。
要注意的是,文件被當做模組導入時,會產生.pyc文件,如果更改了模組,應該刷新.pyc文件,否則讀取的還是舊資訊。
為了防止檔案是被當作模組使用的,我們應該在檔案中加入
if __name__ == '__main__': pass #这里是要执行的语句
这样就可以防止当文件是被用作模块使用时,不会被执行if下面的语句,如果是当做程序来执行时,则会执行下面的语句,一般用作测试。
本文出自 “ptallrights” 博客,请务必保留此出处http://ptallrights.blog.51cto.com/11151122/1793746
以上是python學習之物件導向程式設計特性(二)的詳細內容。更多資訊請關注PHP中文網其他相關文章!