類和對象
類和函數(shù)一樣都是Python中的對象。當(dāng)一個(gè)類定義完成之后,Python將創(chuàng)建一個(gè)“類對象”并將其賦值給一個(gè)同名變量。類是type類型的對象(是不是有點(diǎn)拗口?)。
類對象是可調(diào)用的(callable,實(shí)現(xiàn)了 __call__方法),并且調(diào)用它能夠創(chuàng)建類的對象。你可以將類當(dāng)做其他對象那么處理。例如,你能夠給它們的屬性賦值,你能夠?qū)⑺鼈冑x值給一個(gè)變量,你可以在任何可調(diào)用對象能夠用的地方使用它們,比如在一個(gè)map中。事實(shí)上當(dāng)你在使用map(str, [1,2,3])的時(shí)候,是將一個(gè)整數(shù)類型的list轉(zhuǎn)換為字符串類型的list,因?yàn)閟tr是一個(gè)類。可以看看下面的代碼:
>>> class C(object):... def __init__(self, s):... print s...>>> myclass = C>>> type(C)<type 'type'>>>> type(myclass)<type 'type'>>>> myclass(2)2<__main__.C object at 0x10e2bea50>>>> map(myclass, [1,2,3])123[<__main__.C object at 0x10e2be9d0>, <__main__.C object at 0x10e2bead0>, <__main__.C object at 0x10e2beb10>]>>> map(C, [1,2,3])123[<__main__.C object at 0x10e2be950>, <__main__.C object at 0x10e2beb50>, <__main__.C object at 0x10e2beb90>]>>> C.test_attribute = True>>> myclass.test_attributeTrue
正因如此,Python中的“class”關(guān)鍵字不像其他語言(例如C++)那樣必須出現(xiàn)在代碼main scope中。在Python中,它能夠在一個(gè)函數(shù)中嵌套出現(xiàn),舉個(gè)例子,我們能夠這樣在函數(shù)運(yùn)行的過程中動態(tài)的創(chuàng)建類。看代碼:
>>> def make_class(class_name):... class C(object):... def print_class_name(self):... print class_name... C.__name__ = class_name... return C...>>> C1, C2 = map(make_class, ["C1", "C2"])>>> c1, c2 = C1(), C2()>>> c1.print_class_name()C1>>> c2.print_class_name()C2>>> type(c1)<class '__main__.C1'>>>> type(c2)<class '__main__.C2'>>>> c1.print_class_name.__closure__(<cell at 0x10ab6dbe8: str object at 0x10ab71530>,)
請注意,在這里通過make_class創(chuàng)建的兩個(gè)類是不同的對象,因此通過它們創(chuàng)建的對象就不屬于同一個(gè)類型。正如我們在裝飾器中做的那樣,我們在類被創(chuàng)建之后手動設(shè)置了類名。同樣也請注意所創(chuàng)建類的print_class_name方法在一個(gè)closure cell中捕捉到了類的closure和class_name。如果你對closure的概念還不是很清楚,那么最好去看看前篇,復(fù)習(xí)一下closures和decorators相關(guān)的內(nèi)容。
Metaclasses
如果類是能夠制造對象的對象,那制造類的對象又該叫做什么呢(相信我,這并不是一個(gè)先有雞還是先有蛋的問題)?答案是元類(Metaclasses)。大部分常見的基礎(chǔ)元類都是type。當(dāng)輸入一個(gè)參數(shù)時(shí),type將簡單的返回輸入對象的類型,這就不涉及元類。然而當(dāng)輸入三個(gè)參數(shù)時(shí),type將扮演元類的角色,基于輸入?yún)?shù)創(chuàng)建一個(gè)類并返回。輸入?yún)?shù)相當(dāng)簡單:類名,父類及其參數(shù)的字典。后面兩者可以為空,來看一個(gè)例子:
新聞熱點(diǎn)
疑難解答
圖片精選