Python - 類和物件



Python 是一種面向物件程式語言,這意味著它基於 OOP 概念的原則。Python 程式中使用的實體是某個類的物件。例如,數字、字串、列表、字典以及程式中類似的其他實體都是相應內建類的物件。

在 Python 中,名為Object的類是所有類的基類或父類,包括內建類和使用者定義類。

什麼是 Python 中的類?

在 Python 中,class 是使用者定義的實體(資料型別),它定義了物件可以包含的資料型別以及可以執行的操作。它用作建立物件的模板。例如,如果我們想在 Python 程式中定義一個智慧手機類,我們可以使用 RAM、ROM、螢幕尺寸等資料型別以及撥打電話和傳送簡訊等操作。

在 Python 中建立類

使用class 關鍵字在 Python 中建立一個新類。class關鍵字後緊跟類名,然後是一個冒號,如下所示:

class ClassName:
   'Optional class documentation string'
   class_suite
  • 該類具有一個文件字串,可以透過 ClassName.__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 會呼叫它。

  • 您可以像宣告普通函式一樣宣告其他類方法,區別在於每個方法的第一個引數是self。Python 會為您新增self 引數;呼叫方法時,不需要包含它。

什麼是物件?

一個物件被稱為給定Python類的例項。每個物件都有自己的屬性和方法,這些屬性和方法由其類定義。

建立類時,它只描述物件的結構。當從類例項化物件時,才會分配記憶體。

class object in python

在上圖中,Vehicle是類名,CarBusSUV是它的物件。

在Python中建立類的物件

要建立類的例項,可以使用類名呼叫類,並傳入其__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)

在Python中訪問物件的屬性

可以使用點運算子 object. 來訪問物件的屬性。類變數的訪問方式如下:

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

現在,將所有概念放在一起:

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)

執行上述程式碼後,將產生以下結果:

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

可以隨時新增、刪除或修改類和物件的屬性:

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

除了使用正常的語句訪問屬性外,還可以使用以下函式:

  • getattr(obj, name[, default]) − 訪問物件的屬性。

  • hasattr(obj,name) − 檢查屬性是否存在。

  • setattr(obj,name,value) − 設定屬性。如果屬性不存在,則會建立它。

  • delattr(obj, name) − 刪除屬性。

# Returns true if 'age' attribute exists
hasattr(emp1, 'age')   
# Returns value of 'age' attribute
getattr(emp1, 'age')    
# Set attribute 'age' at 8
setattr(emp1, 'age', 8) 
# Delete attribute 'age'
delattr(empl, 'age')    

Python中的內建類屬性

每個Python類都保留以下內建屬性,可以使用點運算子像任何其他屬性一樣訪問它們:

序號 屬性和描述
1 __dict__

包含類名稱空間的字典。

2 __doc__

類文件字串,如果未定義則為None。

3 __name__

類名

4 __module__

定義類的模組名。在互動模式下,此屬性為“__main__”。

5 __bases__

一個可能為空的元組,包含基類,其順序與其在基類列表中的出現順序相同。

示例

對於上面的Employee類,讓我們嘗試訪問它的屬性:

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__)

執行上述程式碼後,將產生以下結果:

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的type()函式。此函式接受資料型別並返回其對應的類。

示例

以下示例演示如何檢查給定資料型別的內建類。

num = 20
print (type(num))
num1 = 55.50
print (type(num1))
s = "TutorialsPoint"
print (type(s))
dct = {'a':1,'b':2,'c':3}
print (type(dct))
def SayHello():
   print ("Hello World")
   return
print (type(SayHello))

執行此程式碼時,它將顯示Python資料型別的對應類:

<class 'int'>
<class 'float'>
<class 'str'>
<class 'dict'>
<class 'function'>

Python中的垃圾回收(銷燬物件)

Python會自動刪除不需要的物件(內建型別或類例項)以釋放記憶體空間。Python定期回收不再使用的記憶體塊的過程稱為垃圾回收

Python的垃圾收集器在程式執行期間執行,並在物件的引用計數達到零時觸發。物件的引用計數會隨著指向它的別名數量的變化而變化。

當物件被賦予新名稱或放入容器(列表、元組或字典)中時,物件的引用計數會增加。當物件使用del刪除、其引用被重新分配或其引用超出範圍時,物件的引用計數會減少。當物件的引用計數達到零時,Python會自動收集它。

# Create object <40>
a = 40      
# Increase ref. count  of <40> 
b = a       
# Increase ref. count  of <40> 
c = [b]     

# Decrease ref. count  of <40>
del a       
# Decrease ref. count  of <40>
b = 100      
# Decrease ref. count  of <40>
c[0] = -1    

通常情況下,您不會注意到垃圾收集器何時銷燬未使用的例項並回收其空間。但是,類可以實現名為解構函式的特殊方法__del__(),該方法在例項即將被銷燬時呼叫。此方法可用於清理例項使用的任何非記憶體資源。

示例

__del__()解構函式列印即將被銷燬的例項的類名,如下面的程式碼塊所示:

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
# prints the ids of the obejcts
print (id(pt1), id(pt2), id(pt3))
del pt1
del pt2
del pt3

執行後,上述程式碼將產生以下結果:

135007479444176 135007479444176 135007479444176
Point destroyed

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
ERROR!
Traceback (most recent call last):
  File <main.py>", line 11, in <module>
AttributeError: 'JustCounter' object has no attribute '__secretCount'

Python 透過在內部更改名稱以包含類名來保護這些成員。您可以訪問這些屬性,例如 object._className__attrName。如果將最後一行替換為以下內容,則它對您有效:

print(counter._JustCounter__secretCount)

執行上述程式碼後,將產生以下結果:

1
2
2
廣告