[Python]使用type()函數創建類對象
1 人贊了文章
一、初識type函數
type函數常用來判斷對象屬於什麼類型,Python中一切皆對象的理念已深入人心,所以type函數使用頻率也是挺高的。比如:
>>> a = 1>>> b = hello>>> c = [1, 2, 3]>>> d = {name: Tom}>>> e = (1, 2, 3)>>> type(a)<class int>>>> type(b)<class str>>>> type(c)<class list>>>> type(d)<class dict>>>> type(e)<class tuple>
上面出現的幾種對象類型很常見,比如「int」、「str」、「list」、「dict」』等。我們再看看下面的例子:
>>> class Student(object): pass...>>> s = Student()>>> type(s)<class __main__.Student>>>> type(Student)<class type>
對於實例對象s屬於Student類,這個比較容易理解;但是,為什麼Student類對象屬於type類呢?type類又是什麼呢?(注意:類本身也是對象)再看幾個例子:
>>> type(int)<class type>>>> type(str)<class type>>>> type(dict)<class type>>>> type(tuple)<class type>
上面的結果表現的極其一致,結合上面舉的Student類的例子,可以初步得出結論,不管是Python自帶的像「int」、「list」等類對象,還是像Student這樣自定義的類對象(注意:是類對象,不是實例對象),都是屬於type類。
二、再識type函數
除了可以通過type函數判斷對象類型,還可以通過__class__屬性獲取,試試這種方式:
>>> a = 1>>> a.__class__<class int>>>> a.__class__.__class__<class type>>>> a.__class__.__class__.__class__<class type>
對於類對象屬於type類型的結果還沒能接受,現在又冒出來type類也屬於type類的結果,如果你願意繼續測下去,a.__class__.__class__.__class__.__class__的結果還是type。
現在看來,type類真的神秘,到底為何物?
以下是Python官方文檔對type類的解釋:
Type objects represent the various object types. An object』s type is accessed by the built-in function type()
. There are no special operations on types. The standard module types
defines names for all standard built-in types.
Types are written like this: <class
int>
.
大致意思:type類代表了各種各樣的對象類型,像「int」這樣的對象類型是通過type()函數獲取的。所有內置的標準對象類型都在這裡types。
可能有人會有疑惑,為什麼對象類型是通過type()函數創建的呢?明明是通過通過class類進行定義的。這就要涉及到type()函數另一種使用方式了:
classtype
(name,bases,dict)
向type()函數傳入三個參數name,bases,dict(參數稍後解釋),將會返回一個新的type對象(比如內置int對象就是屬於type類,還有自定義Student類對象也屬於type類),至此感覺type()函數好強大,它似乎創造了Python所有的對象,事實也是如此。
等等,我們明明使用class定義的類,怎麼和type()函數扯上關係了呢?當我們使用class定義類的時候,Python解釋器僅僅是掃描一下定義的語法,然後調用type()函數創建class類。那為什麼採取這種方式呢?先看一個例子:
class A(object): # 類屬性 role = student # 實例方法 def __init__(self, name): # 實例屬性 self.name = name # 類方法 @classmethod def study(cls): pass # 靜態方法 @staticmethod def cal_student_num(): pass
上面我們使用class定義了A類對象,其中包含了類屬性、類方法、實例屬性、實例方法、靜態方法。如果我們使用type()函數,如何創建呢?
# 使用type()函數定義類# 實例方法def __init__(self, name): # 實例屬性 self.name = name# 類方法@classmethoddef study(cls): pass# 靜態方法@staticmethoddef cal_student_num(): pass# 元類最大的作用不在於創建一個新的類A = type( A, (object,), { role: student, __init__: __init__, study: study, cal_student_num: cal_student_num })
仔細觀察,使用type()函數創建class類的時候,只是將定義在class類內部的代碼拿出來,放在外面,然後向type()函數傳入三個參數name,bases,dict。name字元串類型,代表類名,比如例子中的"A";bases元組類型,代表基類(或父類),即需要繼承的類對象;dict字典類型,將定義的類屬性、類方法、實例方法等,以鍵值對的形式建立映射關係。
當我們使用class定義對象的時候,解釋器內部會幫我們調用type()函數,完成創建對象工作。為什麼平時我們定義對象大多是採用class,而不採用type()函數呢?因為type()函數一點都不優美,看上去缺少整體性,代碼不易讀,寫起來也很麻煩。(如果一般工作中用type()定義對象,估計要被罵,哈哈??)
說明:
name參數變成__name__
對象屬性,bases參數變成 __bases__
對象屬性,dict參數變成__dict__
對象屬性,分別查看例子中的這三個屬性:
In [6]: A.__class__Out[6]: typeIn [7]: A.__bases__Out[7]: (object,)In [8]: A.__dict__Out[8]:mappingproxy({__dict__: <attribute __dict__ of A objects>, __doc__: None, __init__: <function __main__.__init__>, __module__: __main__, __weakref__: <attribute __weakref__ of A objects>, cal_student_num: <staticmethod at 0x10387ac88>, role: student, study: <classmethod at 0x10387ac18>})
三、小結
- 使用type()函數時,如果只傳入一個參數object,那麼將返回該object的類型;
- 如果分別傳入name,bases,dict這三個參數,那麼type()函數將會創建一個對象;
- 使用class定義對象的時候,Python解釋器調用type()函數來動態創建對象。
推薦閱讀:
※用 Python + POV-Ray 重現 Dimensions 視頻中的效果
※常州房價分析
※用Python爬取微博數據生成詞雲圖片
※Python入門到實踐-字典
※437. Path Sum III
TAG:Python |