深入講解Python中面向?qū)ο缶幊痰南嚓P(guān)知識(shí)
Python從第一天開(kāi)始就是面向?qū)ο蟮恼Z(yǔ)言。正因?yàn)槿绱?,?chuàng)建和使用類(lèi)和對(duì)象是非常地容易。本章將幫助您在使用Python面向?qū)ο缶幊痰募夹g(shù)方面所有提高。
如果沒(méi)有任何以往面向?qū)ο?OO)的編程的經(jīng)驗(yàn),那么可能要了解一些基本的入門(mén)課程就可以了,或者至少某種形式的教程,讓你有了解基本概念。
但是,這里會(huì)比較少地介紹面向?qū)ο缶幊?OOP):
OOP術(shù)語(yǔ)概述
- 類(lèi): 用戶(hù)定義的原型對(duì)象,它定義了一套描述類(lèi)的任何對(duì)象的屬性。屬性是數(shù)據(jù)成員(類(lèi)變量和實(shí)例變量)和方法,通過(guò)點(diǎn)符號(hào)訪問(wèn)。
- 類(lèi)變量:這是一個(gè)類(lèi)的所有實(shí)例共享的變量。類(lèi)變量在類(lèi),但外面的任何類(lèi)的方法定義。類(lèi)變量不被用作經(jīng)常作為實(shí)例變量。
- 數(shù)據(jù)成員:保存與類(lèi)和對(duì)象關(guān)聯(lián)的數(shù)據(jù)的類(lèi)變量或?qū)嵗兞俊?/li>
- 函數(shù)重載:一個(gè)以上的行為特定功能的分配。執(zhí)行的操作所涉及的對(duì)象(自變量)的類(lèi)型不同而不同。
- 實(shí)例變量:所定義的方法內(nèi),只屬于一個(gè)類(lèi)的當(dāng)前實(shí)例的變量。
- 繼承:類(lèi)的特點(diǎn),即都是由它派生其他類(lèi)的轉(zhuǎn)移。
- 實(shí)例:某一類(lèi)的一個(gè)單獨(dú)對(duì)象。屬于類(lèi)Circle一個(gè)obj對(duì)象,例如,是類(lèi)Circle的一個(gè)實(shí)例。
- 實(shí)例化:創(chuàng)建一個(gè)類(lèi)的實(shí)例。
- Method : 一種特殊的函數(shù),函數(shù)在類(lèi)定義中定義。
- 對(duì)象:這是由它的類(lèi)中定義的數(shù)據(jù)結(jié)構(gòu)的唯一實(shí)例。一個(gè)對(duì)象包括兩個(gè)數(shù)據(jù)成員(類(lèi)變量和實(shí)例變量)和方法。
- 運(yùn)算符重載:一個(gè)以上的函數(shù)功能,特定的操作符分配。
創(chuàng)建類(lèi):
類(lèi)語(yǔ)句將創(chuàng)建一個(gè)新的類(lèi)定義。類(lèi)的名稱(chēng)緊跟在關(guān)鍵字class后跟一個(gè)冒號(hào),如下所示:
class ClassName: 'Optional class documentation string' class_suite
類(lèi)有一個(gè)文檔字符串,它可以通過(guò)類(lèi)名.__ doc__訪問(wèn)。
class_suite由所有定義的類(lèi)成員,數(shù)據(jù)屬性與函數(shù)組件的語(yǔ)句。
例子
下面是一個(gè)簡(jiǎn)單的Python類(lèi)的例子:
class Employee: 'Common base class for all employees' 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是一個(gè)類(lèi)變量,其值將是這個(gè)類(lèi)的所有實(shí)例共享。這可以從類(lèi)中或外部進(jìn)行訪問(wèn),訪問(wèn)形式為 Employee.empCount。
第一個(gè)方法__init__()是一種特殊的方法,這就是所謂的類(lèi)構(gòu)造函數(shù)或當(dāng)創(chuàng)建該類(lèi)的一個(gè)新實(shí)例Python調(diào)用的初始化方法。
聲明就像正常函數(shù)中一樣,不同的是第一個(gè)參數(shù)到每個(gè)方法是類(lèi)的方法。 Python增加了self參數(shù)列表;不需要把調(diào)用的方法都它列入。
創(chuàng)建實(shí)例對(duì)象:
要?jiǎng)?chuàng)建一個(gè)類(lèi)的實(shí)例,調(diào)用類(lèi)名并傳遞任何參數(shù)給__init__方法接收。
"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)
訪問(wèn)屬性:
可以訪問(wèn)使用點(diǎn)運(yùn)算符來(lái)訪問(wèn)對(duì)象的屬性。而類(lèi)變量使用類(lèi)名來(lái)訪問(wèn),如下所示:
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
現(xiàn)在,把所有的概念放在一起:
#!/usr/bin/python
class Employee:
'Common base class for all employees'
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
"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount
當(dāng)執(zhí)行上面的代碼,產(chǎn)生以下結(jié)果:
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
在任何時(shí)候可以添加,刪除或修改類(lèi)和對(duì)象的屬性:
emp1.age = 7 # Add an 'age' attribute. emp1.age = 8 # Modify 'age' attribute. del emp1.age # Delete 'age' attribute.
除了使用正常的語(yǔ)句來(lái)訪問(wèn)屬性,可以使用以下函數(shù):
- getattr(obj, name[, default]) : 訪問(wèn)對(duì)象的屬性。
- hasattr(obj,name) : 檢查一個(gè)屬性是否存在。
- setattr(obj,name,value) : 設(shè)置一個(gè)屬性。如果屬性不存在,那么它將被創(chuàng)建。
- delattr(obj, name) : 要?jiǎng)h除一個(gè)屬性。
hasattr(emp1, 'age') # Returns true if 'age' attribute exists getattr(emp1, 'age') # Returns value of 'age' attribute setattr(emp1, 'age', 8) # Set attribute 'age' at 8 delattr(empl, 'age') # Delete attribute 'age'
內(nèi)置的類(lèi)屬性:
每個(gè)Python類(lèi)會(huì)繼續(xù)并帶有內(nèi)置屬性,他們可以使用點(diǎn)運(yùn)算符像任何其他屬性一樣來(lái)訪問(wèn):
- __dict__ : 字典包含類(lèi)的命名空間。
- __doc__ : 類(lèi)的文檔字符串,或None如果沒(méi)有定義。
- __name__: 類(lèi)名稱(chēng)。
- __module__: 在類(lèi)中定義的模塊名稱(chēng)。此屬性是在交互模式其值為“__main__”。
- __bases__ : 一個(gè)可能是空的元組包含了基類(lèi),其在基類(lèi)列表出現(xiàn)的順序。
對(duì)于上面的類(lèi),嘗試訪問(wèn)這些屬性:
#!/usr/bin/python class Employee: 'Common base class for all employees' 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__
當(dāng)執(zhí)行上面的代碼,產(chǎn)生以下結(jié)果:
Employee.__doc__: Common base class for all employees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount':
<function displayCount at 0xb7c84994>, 'empCount': 2,
'displayEmployee': <function displayEmployee at 0xb7c8441c>,
'__doc__': 'Common base class for all employees',
'__init__': <function __init__ at 0xb7c846bc>}
銷(xiāo)毀對(duì)象(垃圾回收):
Python的刪除不需要的對(duì)象(內(nèi)建類(lèi)型或類(lèi)的實(shí)例),自動(dòng)釋放內(nèi)存空間。由Python定期回收的內(nèi)存塊不再使用的過(guò)程被稱(chēng)為垃圾收集。
Python的垃圾回收器在程序執(zhí)行過(guò)程中運(yùn)行,當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)為零時(shí)觸發(fā)。一個(gè)對(duì)象的引用計(jì)數(shù)改變?yōu)橹赶蛩淖儎e名的數(shù)量。
當(dāng)它分配一個(gè)新的名字或放置在容器(列表,元組或字典)的對(duì)象的引用計(jì)數(shù)增加。當(dāng)對(duì)象的引用計(jì)數(shù)減少使用 del 刪除,其基準(zhǔn)被重新分配,或者它的引用超出范圍。當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)變?yōu)榱悖琍ython會(huì)自動(dòng)地收集它。
a = 40 # Create object <40> b = a # Increase ref. count of <40> c = [b] # Increase ref. count of <40> del a # Decrease ref. count of <40> b = 100 # Decrease ref. count of <40> c[0] = -1 # Decrease ref. count of <40>
當(dāng)垃圾回收器銷(xiāo)毀孤立的實(shí)例,并回收其空間一般不會(huì)注意到。但是,一個(gè)類(lèi)可以實(shí)現(xiàn)特殊方法__del__(),稱(chēng)為析構(gòu)函數(shù)被調(diào)用時(shí),該實(shí)例將被摧毀。這個(gè)方法可以用于清理所用的一個(gè)實(shí)例的任何非內(nèi)存資源。
例子:
__del__()析構(gòu)函數(shù)打印實(shí)例,它即將被銷(xiāo)毀的類(lèi)名:
#!/usr/bin/python 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) # prints the ids of the obejcts del pt1 del pt2 del pt3
當(dāng)執(zhí)行上面的代碼,它產(chǎn)生以下結(jié)果:
3083401324 3083401324 3083401324 Point destroyed
注意:理想情況下,應(yīng)該定義類(lèi)的單獨(dú)的文件,那么應(yīng)該使用import語(yǔ)句將其導(dǎo)入主程序文件。詳細(xì)請(qǐng)查看Python- 模塊章節(jié),導(dǎo)入模塊和類(lèi)的更多細(xì)節(jié)。
類(lèi)繼承:
不用從頭開(kāi)始,可以通過(guò)上面列出的括號(hào)父類(lèi)的新類(lèi)名后,從一個(gè)已經(jīng)存在的類(lèi)派生它創(chuàng)建一個(gè)類(lèi)。
子類(lèi)繼承父類(lèi)的屬性,可以使用父類(lèi)的這些屬性,就好像它們是在子類(lèi)中定義的一樣。子類(lèi)也可以覆蓋父類(lèi)的數(shù)據(jù)成員和方法。
語(yǔ)法
派生類(lèi)的聲明很像它們的父類(lèi); 從基類(lèi)的列表后給出類(lèi)名繼承:
class SubClassName (ParentClass1[, ParentClass2, ...]): 'Optional class documentation string' class_suite
例子
#!/usr/bin/python class Parent: # define parent class parentAttr = 100 def __init__(self): print "Calling parent constructor" def parentMethod(self): print 'Calling parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent attribute :", Parent.parentAttr class Child(Parent): # define child class def __init__(self): print "Calling child constructor" def childMethod(self): print 'Calling child method' c = Child() # instance of child c.childMethod() # child calls its method c.parentMethod() # calls parent's method c.setAttr(200) # again call parent's method c.getAttr() # again call parent's method
當(dāng)執(zhí)行上面的代碼,產(chǎn)生以下結(jié)果:
Calling child constructor Calling child method Calling parent method Parent attribute : 200
類(lèi)似的方式,可以按如下繼承多個(gè)父類(lèi)的類(lèi):
.....
class B: # define your calss B
.....
class C(A, B): # subclass of A and B
.....
可以使用issubclass()或isinstance()函數(shù)來(lái)檢查兩個(gè)類(lèi)和實(shí)例的關(guān)系。
- issubclass(sub, sup) 如果給定的子類(lèi)子確實(shí)是超sup的子類(lèi)布爾函數(shù)返回true。
- isinstance(obj, Class) 如果obj是Class類(lèi)的實(shí)例,或者是類(lèi)的一個(gè)子類(lèi)的實(shí)例布爾函數(shù)返回true
重寫(xiě)方法:
可以覆蓋父類(lèi)的方法。原因之一重寫(xiě)父的方法,因?yàn)榭赡芟朐谧宇?lèi)特殊或?qū)崿F(xiàn)不同的功能。
例子
#!/usr/bin/python class Parent: # define parent class def myMethod(self): print 'Calling parent method' class Child(Parent): # define child class def myMethod(self): print 'Calling child method' c = Child() # instance of child c.myMethod() # child calls overridden method
當(dāng)執(zhí)行上面的代碼,產(chǎn)生以下結(jié)果:
Calling child method
基礎(chǔ)重載方法:
下表列出了一些通用的功能,可以在類(lèi)重寫(xiě)中:

重載運(yùn)算符:
假設(shè)要?jiǎng)?chuàng)建了一個(gè)Vector類(lèi)來(lái)表示二維向量,當(dāng)使用加運(yùn)算符來(lái)增加他們發(fā)生了什么?最有可能是Python會(huì)理你。
可以,但是定義__add__方法在類(lèi)中進(jìn)行矢量相加,再加上操作符的行為會(huì)按預(yù)期:
例子:
#!/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) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
當(dāng)執(zhí)行上面的代碼,產(chǎn)生以下結(jié)果:
Vector(7,8)
數(shù)據(jù)隱藏:
對(duì)象的屬性可以是或可以不在類(lèi)定義外部可見(jiàn)。對(duì)于這些情況,可以命名以雙下劃線(xiàn)前綴屬性,這些屬性將無(wú)法直接讓外部可視。
例子:
#!/usr/bin/python class JustCounter: __secretCount = 0 def count(self): self.__secretCount += 1 print self.__secretCount counter = JustCounter() counter.count() counter.count() print counter.__secretCount
當(dāng)執(zhí)行上面的代碼,產(chǎn)生以下結(jié)果:
1 2 Traceback (most recent call last): File "test.py", line 12, in <module> print counter.__secretCount AttributeError: JustCounter instance has no attribute '__secretCount'
Python的保護(hù)成員通過(guò)內(nèi)部更改名稱(chēng)以包含類(lèi)名??梢栽L問(wèn)這些屬性通過(guò)object._className__attrName。如果想更換最后一行,那么它會(huì)工作如下:
......................... print counter._JustCounter__secretCount
當(dāng)執(zhí)行上面的代碼,產(chǎn)生以下結(jié)果:
1 2 2
- Python面向?qū)ο缶幊讨械念?lèi)和對(duì)象學(xué)習(xí)教程
- 簡(jiǎn)述Python中的面向?qū)ο缶幊痰母拍?/a>
- Python3.5面向?qū)ο缶幊虉D文與實(shí)例詳解
- Python面向?qū)ο缶幊讨^承與多態(tài)詳解
- 舉例講解Python面向?qū)ο缶幊讨蓄?lèi)的繼承
- 關(guān)于Python面向?qū)ο缶幊痰闹R(shí)點(diǎn)總結(jié)
- Python面向?qū)ο缶幊讨嘘P(guān)于類(lèi)和方法的學(xué)習(xí)筆記
- 談一談基于python的面向?qū)ο缶幊袒A(chǔ)
- Python面向?qū)ο缶幊袒A(chǔ)實(shí)例分析
相關(guān)文章
2款Python內(nèi)存檢測(cè)工具介紹和使用方法
這篇文章主要介紹了2款Python內(nèi)存檢測(cè)工具介紹和使用方法,可以用來(lái)分析Python程序的內(nèi)存使用量,需要的朋友可以參考下2014-06-06
python 實(shí)現(xiàn)生成均勻分布的點(diǎn)
今天小編就為大家分享一篇python 實(shí)現(xiàn)生成均勻分布的點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
Python Playwright安裝和基本使用問(wèn)題記錄
這篇文章主要介紹了Playwright安裝和基本使用問(wèn)題記錄,playwright是一款新型的自動(dòng)化測(cè)試工具,功能非常強(qiáng)大,有很多優(yōu)點(diǎn),缺點(diǎn)就是使用的人比較少,本文通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05
Python編程實(shí)現(xiàn)的圖片識(shí)別功能示例
這篇文章主要介紹了Python編程實(shí)現(xiàn)的圖片識(shí)別功能,涉及Python PIL模塊的安裝與使用技巧,需要的朋友可以參考下2017-08-08
python計(jì)算最小優(yōu)先級(jí)隊(duì)列代碼分享
python計(jì)算最小優(yōu)先級(jí)隊(duì)列代碼分享,大家參考使用吧2013-12-12
Python面向?qū)ο笾鄳B(tài)原理與用法案例分析
這篇文章主要介紹了Python面向?qū)ο笾鄳B(tài)原理與用法,結(jié)合具體案例形式分析了Python多態(tài)的具體功能、原理、使用方法與操作注意事項(xiàng),需要的朋友可以參考下2019-12-12
多個(gè)版本的python共存時(shí)使用pip的正確做法
這篇文章主要介紹了多版本python共存時(shí)使用pip的正確做法,幫助有多個(gè)python版本需求的人可以正確的導(dǎo)包,感興趣的朋友可以了解下2020-10-10
Python+django實(shí)現(xiàn)文件上傳
本系列以可操作性為主,介紹如何通過(guò)django web框架來(lái)實(shí)現(xiàn)一些簡(jiǎn)單的功能。每一篇文章都具有完整性和獨(dú)立性。使用新手在動(dòng)手做的過(guò)程中體會(huì)web開(kāi)發(fā)的過(guò)程,過(guò)程中細(xì)節(jié)請(qǐng)參考相關(guān)文檔。2016-01-01
Python模擬伯努利試驗(yàn)和二項(xiàng)分布代碼實(shí)例
這篇文章主要介紹了Python模擬伯努利試驗(yàn)和二項(xiàng)分布代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05

