Python|全面細說Python的類(class)與對象(object)

函數是抽象層,封裝了算法的流程細節。模塊是抽象層,可以用模塊名稱來組織或思考一個整體功能,而類可能將對象的狀態(數據或屬性)與功能(方法或對象的函數)“粘”(封裝)在一起。將數據分類、數據操作(數據上的算法)、數據結構的邏輯關係(繼承、多態)等結合到了一起(封裝)。

目錄

1 The benefits of class

2 創建類

3 創建實例對象

4 訪問對象成員

5 類的內置類屬性

6 類的__new__()、構造函數__init__()方法、析構函數__del__等特殊方法

7 實例屬性和類屬性

8 私有成員和公有成員

9 動態增加類或對象成員

10 以函數的方式訪問對象屬性

11 類的繼承

12 方法的重載

13 運算符重載

14 單下劃線、雙下劃線、頭尾雙下劃線的使用

1 The benefits of class:

1.1 for protecting data ;

1.2 for easy to maintain the class.

1.3 for reusing of code.

1.4 self-defining data type.

2 創建類

使用 class 語句來創建一個新類,class 之後為類的名稱並以冒號結尾:

Python|全面細說Python的類(class)與對象(object)

Define the initializer, create data fields, and define methods.

The name of the initializer is __init__.

The self refers to the object itself. Through self, the members of the object can be accessed.

在類的內部,使用 def 關鍵字可以為類定義一個方法,與一般函數定義不同,類方法必須包含參數 self,且為第一個參數。

Python中的所有類都派生於object類,所以類定義時也可以寫成class myclassname(object):

3 創建實例對象

Python在創建對象是,分為兩個階段:第一個階段,對象是通過調用__new__()方法來創建的。__new__()方法並不會立即返回一個對象實例,__new__()方法之後,會調用__init__()方法來給對象增加初始的屬性。

The syntax for constructing an object is

wh01 = Employee('wwu',5000)

實例化一個類的語法,其他編程語言中一般用關鍵字 new,但是在 Python 中並沒有這個關鍵字,類的實例化類似函數調用方式。

The arguments of the constructor match the parameters in the __init__ method without self.

The constructor first creates an object in the memory and then invokes the initializer. Initializer is a special method that is called when creating an object.

Given the declaration x = Circle(), x contains a reference to a Circle object.

4 訪問對象成員

The object member access operator is the dot (.)

可以使用點號 . 來訪問對象的屬性。使用如下類的名稱訪問實例變量:

print(wh01.name)

wh01.displayEmployee()

還可以以函數的方式訪問屬性,見第10節。

5 類的內置類屬性

類的內置類屬性包括:

__doc__ :類的文檔字符串

__name__: 類名

__module__: 類定義所在的模塊(類的全名是'__main__.className',如果類位於一個導入模塊mymod中,那麼className.__module__ 等於 mymod)

__bases__ : 類的所有父類構成元素(包含了一個由所有父類組成的元組)

__dict__ : 類的屬性(包含一個字典,由類的數據屬性組成)

如:class_name = self.__class__.__name__

參考:http://www.runoob.com/python/python-object.html

6 類的__new__()、構造函數__init__()方法、析構函數__del__等特殊方法

__new__()方法可以返回對象,如果返回的對象是第一個參數的類實例,接下來就會執行__init__()方法,__init__()方法的第一個參數就是__new__()返回的對象。__new__()如果沒有返回第一個參數的類實例(返回別的實例或None),就不會執行__init__()方法。

當第一次創建一個新的類的實例時,Python會檢查是否定義了一個__init__函數。如果已經定義了,將運行這個函數,可以通過類似self.name = 'wwu'的格式讓對象初始化值;

能夠創建一個帶有值的實例非常有用。__init__函數除了初始化對象以外,還可以做其它普通成員方法可以做的事件(定義代碼)。

__init__()方法使用雙下劃線,是為了儘量確保名字的唯一性;

在Python中,對象方法的第一個參數一定是對象本身self。在類的成員函數中訪問實例屬性時需要以self為前綴,但在外部通過對象名調用對象成員函數時並不需要傳遞這個參數,如果在外部通過類名調用對象成員函數需要顯式為self參數傳值。

7 實例屬性和類屬性

在構造函數__init__()中定義的,以self為前綴的屬性稱為實例屬性,可以在類的外部,通過對象名訪問。

類屬性是指在類的內部、類方法的外部定義的屬性,可以通過對象名也可以通過類名進行訪問。

Python|全面細說Python的類(class)與對象(object)

上面的num是一個類屬性或叫類變量,它的值將在這個類的所有實例之間共享。你可以在類內部或類外部使用Person.num訪問。

8 私有成員和共有成員

Python並沒有對私有成員提供嚴格的訪問保護機制。在定義類的成員時,如果成員名以兩個下劃線“__”開頭則表示私有成員(相當於C++的private),否則是公有成員。私有成員只能在類的成員方法(類的內部)訪問,在類的外部不能直接訪問,需要通過調用對象的公有成員方法來訪問,或者通過Python支持的特殊方式來訪問。如:

對象名_類名+私有成員

如訪問Car類私有成員__weight

car1._Car__weight

(注意類名的前面是單下劃線)

8.1 私有數據成員和公有數據成員

兩個下劃線開頭,聲明該屬性為私有,不能在類的外部被使用或直接訪問(實例化之後不能被調用)。

定義內部屬性:self.__privateAttrs

Analyze the following code:

class A:

....def __init__(self):

........self.x = 1

........self.__y = 1

....def getY(self):

........return self.__y

a = A()

print(a.__y)

The program has an error because y is private and cannot be access outside of the class.

print(a._A__y) is right.

8.2 公有方法、私有方法、靜態成員

私有方法的名字以兩個下線劃線"__"開始,聲明該方法為私有方法,不能在類的外部調用(實例化之後不能被調用)。在類的內部調用 self.__privateMethods()

私有方法在外部只能通過Python支持的特殊方式來調用。

如果通過類名來調用屬於對象的公有方法,需要顯式為該方法的self參數傳遞一個對象名,用來明確指定訪問哪個對象的數據成員。

靜態方法可以通過類名和對象名調用,但不能直接訪問屬於對象的成員,只能訪問屬於類的成員。靜態方法定義時,需在定義前標註為@staticmethod。

Python|全面細說Python的類(class)與對象(object)

定義在類中,沒有定義任何參數的方法被稱為未綁定方法(Unbound method),這類方法充其量只是將類名稱作為命名空間,可以通過類名稱來調用它,或用函數對象進行調用。

如果在定義類時希望某個方法不被拿來作為綁定方法,可用使用@staticmethod加以標註。

9 動態增加類或對象成員

在Python中比較特殊的是,可以動態地為類和對象增加成員,這一點和很多面向對象程序設計語言不同,也是Python動態類型特點的一種重要體現。

Python|全面細說Python的類(class)與對象(object)

10 以函數的方式訪問對象屬性

對象屬性除於可以通過以實例名稱和句點符號“.”做為前綴來訪問以外,也可以通過函數的方式來訪問

getattr(obj, name) 訪問對象的屬性;

hasattr(obj, name) 檢查是否存在一個屬性;

setattr(obj, name, value) 設置一個屬性,如果屬性不存在,會創建一個新屬性;

delattr(obj, name) 刪除屬性

11 類的繼承

面向對象的編程帶來的主要好處之一是代碼的重用,實現這種重用的方法之一是通過繼承機制。

編寫類時,並非總是要從空白開始。如果你要編寫的類是另一個現成類的特殊版本,可使用繼承。一個類繼承另一個類時,它將自動獲得另一個類的所有屬性和方法;原有的類稱為父類 ,而新類稱為子類 。子類繼承了其父類的所有屬性和方法,同時還可以定義自己的屬性和方法。

通過繼承創建的新類稱為子類派生類,被繼承的類稱為基類父類超類

類名稱旁邊多了個括號,並指定了類,這在Python中代表著繼承了該類。

類繼承語法:

class 派生類名(基類名):

....派生類成員

Python|全面細說Python的類(class)與對象(object)

子類調用父類的方法可以使用super(),如super().parentMethod()

12 方法的重載

重載必須出現在繼承中。它是指當派生類繼承了其類的方法之後,如果基類方法的功能不能滿足需求,需要對基類中的某些方法進行修改,可以在派生類重寫基類的方法。

Python|全面細說Python的類(class)與對象(object)

以下一些特殊方法也可以重載:

I __init__ ( self [,args...] )

構造函數

簡單的調用方法: obj = className(args)

II __del__( self )

析構方法, 刪除一個對象

簡單的調用方法 : del obj

III __repr__( self )

轉化為供解釋器讀取的形式

簡單的調用方法 : repr(obj)

IV __str__( self )

用於將值轉化為適於人閱讀的形式

簡單的調用方法 : str(obj)

V __cmp__ ( self, x )

對象比較

簡單的調用方法 : cmp(obj, x)

13 運算符重載

修改操作符的行為以便它能夠作用於用戶定義類型,這個過程稱為操作符重載。對每一個操作符,Python都提供了一個對應的特殊方法,如__add__對應+號操作符。

操作符重載就是修改一個類似+號這樣操作符的行為,使之可以用於用戶定義的類型。

操作符重載的本質還是一個函數,一個引用用戶自定義類型的對象作為參數的函數。

對象常見的+-*/等操作分別由__add__、__sub__、__mul__、__truediv__方法來定義或重寫。

Python|全面細說Python的類(class)與對象(object)

To concatenate two strings s1 and s2 into s3, use _________.

s3 = s1 + s2 或

s3 = s1.__add__(s2)

To retrieve the character at index 3 from string s, use _________.

s[3] 或

s.__getitem__(3)

To return the length of string s, use _________.

s.__len__() 或

len(s)

14 單下劃線、雙下劃線、頭尾雙下劃線的使用

__foo__: 定義的是特殊方法,一般是系統定義名字 ,類似 __init__() 之類的。

_foo: 以單下劃線開頭的表示的是 protected 類型的變量,即保護類型只能允許其本身與子類進行訪問,不能用於 from module import *

__foo: 雙下劃線的表示的是私有類型(private)的變量, 只能是允許這個類本身進行訪問了,子類內部成員方法也不能訪問到這個私有成員。變通的方法是可以通過“對象名_類名__xxx”這樣的特殊方式訪問。

-End-


分享到:


相關文章: