深入講解Python中物件導向編程的相關知識

來源:互聯網
上載者:User
Python從第一天開始就是物件導向的語言。正因為如此,建立和使用類和對象是非常地容易。本章將協助您在使用Python物件導向編程的技術方面所有提高。

如果沒有任何以往物件導向(OO)的編程的經驗,那麼可能要瞭解一些基本的入門課程就可以了,或者至少某種形式的教程,讓你有瞭解基本概念。

但是,這裡會比較少地介紹物件導向編程(OOP):
OOP術語概述

  • 類: 使用者定義的原型對象,它定義了一套描述類的任何對象的屬性。屬性是資料成員(類變數和執行個體變數)和方法,通過點符號訪問。
  • 類變數:這是一個類的所有執行個體共用的變數。類變數在類,但外面的任何類的方法定義。類變數不被用作經常作為執行個體變數。
  • 資料成員:儲存與類和對象關聯的資料的類變數或執行個體變數。
  • 函數重載:一個以上的行為特定功能的分配。執行的操作所涉及的對象(自變數)的類型不同而不同。
  • 執行個體變數:所定義的方法內,只屬於一個類的當前執行個體的變數。
  • 繼承:類的特點,即都是由它派生其他類的轉移。
  • 執行個體:某一類的一個單獨對象。屬於類Circle一個obj對象,例如,是類Circle的一個執行個體。
  • 執行個體化:建立一個類的執行個體。
  • Method : 一種特殊的函數,函數在類定義中定義。
  • 對象:這是由它的類中定義的資料結構的唯一執行個體。一個對象包括兩個資料成員(類變數和執行個體變數)和方法。
  • 運算子多載:一個以上的函數功能,特定的操作符分配。

建立類:

類語句將建立一個新的類定義。類的名稱緊跟在關鍵字class後跟一個冒號,如下所示:

class ClassName:  'Optional class documentation string'  class_suite

類有一個文檔字串,它可以通過類名.__ doc__訪問。

class_suite由所有定義的類成員,資料屬性與函數組件的語句。

例子

下面是一個簡單的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

empCount是一個類變數,其值將是這個類的所有執行個體共用。這可以從類中或外部進行訪問,訪問形式為 Employee.empCount。

第一個方法__init__()是一種特殊的方法,這就是所謂的類建構函式或當建立該類的一個新執行個體Python調用的初始化方法。

聲明就像正常函數中一樣,不同的是第一個參數到每個方法是類的方法。 Python增加了self參數列表;不需要把調用的方法都它列入。

建立執行個體對象:

要建立一個類的執行個體,調用類名並傳遞任何參數給__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)

訪問屬性:

可以訪問使用點運算子來訪問對象的屬性。而類變數使用類名來訪問,如下所示:

emp1.displayEmployee()emp2.displayEmployee()print "Total Employee %d" % Employee.empCount

現在,把所有的概念放在一起:

#!/usr/bin/pythonclass 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

當執行上面的代碼,產生以下結果:

Name : Zara ,Salary: 2000Name : Manni ,Salary: 5000Total Employee 2

在任何時候可以添加,刪除或修改類和對象的屬性:

emp1.age = 7 # Add an 'age' attribute.emp1.age = 8 # Modify 'age' attribute.del emp1.age # Delete 'age' attribute.

除了使用正常的語句來訪問屬性,可以使用以下函數:

  • getattr(obj, name[, default]) : 訪問對象的屬性。
  • hasattr(obj,name) : 檢查一個屬性是否存在。
  • setattr(obj,name,value) : 設定一個屬性。如果屬性不存在,那麼它將被建立。
  • delattr(obj, name) : 要刪除一個屬性。
hasattr(emp1, 'age')  # Returns true if 'age' attribute existsgetattr(emp1, 'age')  # Returns value of 'age' attributesetattr(emp1, 'age', 8) # Set attribute 'age' at 8delattr(empl, 'age')  # Delete attribute 'age'

內建的類屬性:

每個Python類會繼續並帶有內建屬性,他們可以使用點運算子像任何其他屬性一樣來訪問:

  • __dict__ : 字典包含類的命名空間。
  • __doc__ : 類的文檔字串,或None如果沒有定義。
  • __name__: 類名稱。
  • __module__: 在類中定義的模組名稱。此屬性是在互動模式其值為“__main__”。
  • __bases__ : 一個可能是空的元組包含了基類,其在基類列表出現的順序。

對於上面的類,嘗試訪問這些屬性:

#!/usr/bin/pythonclass 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.salaryprint "Employee.__doc__:", Employee.__doc__print "Employee.__name__:", Employee.__name__print "Employee.__module__:", Employee.__module__print "Employee.__bases__:", Employee.__bases__print "Employee.__dict__:", Employee.__dict__

當執行上面的代碼,產生以下結果:

Employee.__doc__: Common base class for all employeesEmployee.__name__: EmployeeEmployee.__module__: __main__Employee.__bases__: ()Employee.__dict__: {'__module__': '__main__', 'displayCount':, 'empCount': 2, 'displayEmployee': , '__doc__': 'Common base class for all employees', '__init__': }

銷毀對象(記憶體回收):

Python的刪除不需要的對象(內建類型或類的執行個體),自動釋放記憶體空間。由Python定期回收的記憶體塊不再使用的過程被稱為垃圾收集。

Python的記憶體回收行程在程式執行過程中運行,當一個對象的引用計數為零時觸發。一個對象的引用計數改變為指向它改變別名的數量。

當它分配一個新的名字或放置在容器(列表,元組或字典)的對象的引用計數增加。當對象的引用計數減少使用 del 刪除,其基準被重新分配,或者它的引用超出範圍。當一個對象的引用計數變為零,Python會自動地收集它。

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> 

當記憶體回收行程銷毀孤立的執行個體,並回收其空間一般不會注意到。但是,一個類可以實現特殊方法__del__(),稱為解構函式被調用時,該執行個體將被摧毀。這個方法可以用於清理所用的一個執行個體的任何非記憶體資源。
例子:

__del__()解構函式列印執行個體,它即將被銷毀的類名:

#!/usr/bin/pythonclass 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 = pt1pt3 = pt1print id(pt1), id(pt2), id(pt3) # prints the ids of the obejctsdel pt1del pt2del pt3

當執行上面的代碼,它產生以下結果:

3083401324 3083401324 3083401324Point destroyed 

注意:理想情況下,應該定義類的單獨的檔案,那麼應該使用import語句將其匯入主程式檔案。詳細請查看Python- 模組章節,匯入模組和類的更多細節。
類繼承:

不用從頭開始,可以通過上面列出的括弧父類的新類名後,從一個已經存在的類派生它建立一個類。

子類繼承父類的屬性,可以使用父類的這些屬性,就好像它們是在子類中定義的一樣。子類也可以覆蓋父類的資料成員和方法。
文法

衍生類別的聲明很像它們的父類; 從基類的列表後給出類名繼承:

class SubClassName (ParentClass1[, ParentClass2, ...]):  'Optional class documentation string'  class_suite

例子

#!/usr/bin/pythonclass 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.parentAttrclass Child(Parent): # define child class  def __init__(self):   print "Calling child constructor"  def childMethod(self):   print 'Calling child method'c = Child()     # instance of childc.childMethod()   # child calls its methodc.parentMethod()   # calls parent's methodc.setAttr(200)    # again call parent's methodc.getAttr()     # again call parent's method

當執行上面的代碼,產生以下結果:

Calling child constructorCalling child methodCalling parent methodParent attribute : 200

類似的方式,可以按如下繼承多個父類的類:

複製代碼 代碼如下:

class A: # define your class A
.....

class B: # define your calss B
.....

class C(A, B): # subclass of A and B
.....

可以使用issubclass()或isinstance()函數來檢查兩個類和執行個體的關係。

  • issubclass(sub, sup) 如果給定的子類子確實是超sup的子類布爾函數返回true。
  • isinstance(obj, Class) 如果obj是Class類的執行個體,或者是類的一個子類的執行個體布爾函數返回true

重寫方法:

可以覆蓋父類的方法。原因之一重寫父的方法,因為可能想在子類特殊或實現不同的功能。
例子

#!/usr/bin/pythonclass 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 childc.myMethod()     # child calls overridden method

當執行上面的代碼,產生以下結果:

Calling child method

基礎重載方法:

下表列出了一些通用的功能,可以在類重寫中:

重載運算子:

假設要建立了一個Vector類來表示二維向量,當使用加運算子來增加他們發生了什嗎?最有可能是Python會屌你。

可以,但是定義__add__方法在類中進行向量相加,再加上操作符的行為會按預期:
例子:

#!/usr/bin/pythonclass 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

當執行上面的代碼,產生以下結果:

Vector(7,8)

資料隱藏:

對象的屬性可以是或可以不在類定義外部可見。對於這些情況,可以命名以雙底線首碼屬性,這些屬性將無法直接讓外部可視。
例子:

#!/usr/bin/pythonclass JustCounter:  __secretCount = 0   def count(self):   self.__secretCount += 1   print self.__secretCountcounter = JustCounter()counter.count()counter.count()print counter.__secretCount

當執行上面的代碼,產生以下結果:

12Traceback (most recent call last): File "test.py", line 12, in   print counter.__secretCountAttributeError: JustCounter instance has no attribute '__secretCount'

Python的保護成員通過內部更改名稱以包含類名。可以訪問這些屬性通過object._className__attrName。如果想更換最後一行,那麼它會工作如下:

.........................print counter._JustCounter__secretCount

當執行上面的代碼,產生以下結果:

122
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.