函數是抽象層,封裝了算法的流程細節。模塊是抽象層,可以用模塊名稱來組織或思考一個整體功能,而類可能將對象的狀態(數據或屬性)與功能(方法或對象的函數)“粘”(封裝)在一起。將數據分類、數據操作(數據上的算法)、數據結構的邏輯關係(繼承、多態)等結合到了一起(封裝)。
目錄
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 之後為類的名稱並以冒號結尾:
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為前綴的屬性稱為實例屬性,可以在類的外部,通過對象名訪問。
類屬性是指在類的內部、類方法的外部定義的屬性,可以通過對象名也可以通過類名進行訪問。
上面的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。
定義在類中,沒有定義任何參數的方法被稱為未綁定方法(Unbound method),這類方法充其量只是將類名稱作為命名空間,可以通過類名稱來調用它,或用函數對象進行調用。
如果在定義類時希望某個方法不被拿來作為綁定方法,可用使用@staticmethod加以標註。
9 動態增加類或對象成員
在Python中比較特殊的是,可以動態地為類和對象增加成員,這一點和很多面向對象程序設計語言不同,也是Python動態類型特點的一種重要體現。
10 以函數的方式訪問對象屬性
對象屬性除於可以通過以實例名稱和句點符號“.”做為前綴來訪問以外,也可以通過函數的方式來訪問
getattr(obj, name) 訪問對象的屬性;
hasattr(obj, name) 檢查是否存在一個屬性;
setattr(obj, name, value) 設置一個屬性,如果屬性不存在,會創建一個新屬性;
delattr(obj, name) 刪除屬性
11 類的繼承
面向對象的編程帶來的主要好處之一是代碼的重用,實現這種重用的方法之一是通過繼承機制。
編寫類時,並非總是要從空白開始。如果你要編寫的類是另一個現成類的特殊版本,可使用繼承。一個類繼承另一個類時,它將自動獲得另一個類的所有屬性和方法;原有的類稱為父類 ,而新類稱為子類 。子類繼承了其父類的所有屬性和方法,同時還可以定義自己的屬性和方法。
通過繼承創建的新類稱為子類或派生類,被繼承的類稱為基類、父類或超類。
類名稱旁邊多了個括號,並指定了類,這在Python中代表著繼承了該類。
類繼承語法:
class 派生類名(基類名):
....派生類成員
子類調用父類的方法可以使用super(),如super().parentMethod()
12 方法的重載
重載必須出現在繼承中。它是指當派生類繼承了其類的方法之後,如果基類方法的功能不能滿足需求,需要對基類中的某些方法進行修改,可以在派生類重寫基類的方法。
以下一些特殊方法也可以重載:
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__方法來定義或重寫。
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-
閱讀更多 小智雅匯 的文章