程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 講解Python中面向對象編程的相關知識

講解Python中面向對象編程的相關知識

編輯:更多關於編程

       這篇文章主要介紹了深入講解Python中面向對象編程的相關知識,是Python入門學習中的基礎知識,需要的朋友可以參考下

      Python從第一天開始就是面向對象的語言。正因為如此,創建和使用類和對象是非常地容易。本章將幫助您在使用Python面向對象編程的技術方面所有提高。

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

      但是,這裡會比較少地介紹面向對象編程(OOP):

      OOP術語概述

      類: 用戶定義的原型對象,它定義了一套描述類的任何對象的屬性。屬性是數據成員(類變量和實例變量)和方法,通過點符號訪問。

      類變量:這是一個類的所有實例共享的變量。類變量在類,但外面的任何類的方法定義。類變量不被用作經常作為實例變量。

      數據成員:保存與類和對象關聯的數據的類變量或實例變量。

      函數重載:一個以上的行為特定功能的分配。執行的操作所涉及的對象(自變量)的類型不同而不同。

      實例變量:所定義的方法內,只屬於一個類的當前實例的變量。

      繼承:類的特點,即都是由它派生其他類的轉移。

      實例:某一類的一個單獨對象。屬於類Circle一個obj對象,例如,是類Circle的一個實例。

      實例化:創建一個類的實例。

      Method : 一種特殊的函數,函數在類定義中定義。

      對象:這是由它的類中定義的數據結構的唯一實例。一個對象包括兩個數據成員(類變量和實例變量)和方法。

      運算符重載:一個以上的函數功能,特定的操作符分配。

      創建類:

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

      ?

    1 2 3 class ClassName: 'Optional class documentation string' class_suite

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

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

      例子

      下面是一個簡單的Python類的例子:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 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__方法接收。

      ?

    1 2 3 4 "This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000)

      訪問屬性:

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

      ?

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

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

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/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

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

      ?

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

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

      ?

    1 2 3 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) : 要刪除一個屬性。

      ?

    1 2 3 4 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'

      內置的類屬性:

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

      __dict__ : 字典包含類的命名空間。

      __doc__ : 類的文檔字符串,或None如果沒有定義。

      __name__: 類名稱。

      __module__: 在類中定義的模塊名稱。此屬性是在交互模式其值為“__main__”。

      __bases__ : 一個可能是空的元組包含了基類,其在基類列表出現的順序。

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

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #!/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__

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

      ?

    1 2 3 4 5 6 7 8 9 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>}

      銷毀對象(垃圾回收):

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

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

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

      ?

    1 2 3 4 5 6 7 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__()析構函數打印實例,它即將被銷毀的類名:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #!/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

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

      ?

    1 2 3083401324 3083401324 3083401324 Point destroyed

      注意:理想情況下,應該定義類的單獨的文件,那麼應該使用import語句將其導入主程序文件。詳細請查看Python- 模塊章節,導入模塊和類的更多細節。

      類繼承:

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

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

      語法

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

      ?

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

      例子

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #!/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

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

      ?

    1 2 3 4 Calling child constructor Calling child method Calling parent method Parent 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

      重寫方法:

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

      例子

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 #!/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

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

      ?

    1 Calling child method

      基礎重載方法:

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

    201552594506273.jpg (580×426)

      重載運算符:

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

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

      例子:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #!/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

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

      ?

    1 Vector(7,8)

      數據隱藏:

      對象的屬性可以是或可以不在類定義外部可見。對於這些情況,可以命名以雙下劃線前綴屬性,這些屬性將無法直接讓外部可視。

      例子:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 #!/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

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

      ?

    1 2 3 4 5 6 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的保護成員通過內部更改名稱以包含類名。可以訪問這些屬性通過object._className__attrName。如果想更換最後一行,那麼它會工作如下:

      ?

    1 2 ......................... print counter._JustCounter__secretCount

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

      ?

    1 2 3 1 2 2
    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved