type()
動態語言和靜態語言最大的不同,就是函數和類的定義,不是編譯時定義的,而是運行時動態創建的。
比方說我們要定義一個Hello的class,就寫一個hello.py模塊:
class Hello(object): def hello(self, name='world'): print('Hello, %s.' % name)
當Python解釋器載入hello模塊時,就會依次執行該模塊的所有語句,執行結果就是動態創建出一個Hello的class對象,測試如下:
>>> from hello import Hello>>> h = Hello()>>> h.hello()Hello, world.>>> print(type(Hello))<type 'type'>>>> print(type(h))<class 'hello.Hello'>
type()函數可以查看一個類型或變量的類型,Hello是一個class,它的類型就是type,而h是一個實例,它的類型就是class Hello。
我們說class的定義是運行時動態創建的,而創建class的方法就是使用type()函數。
type()函數既可以返回一個對象的類型,又可以創建出新的類型,比如,我們可以通過type()函數創建出Hello類,而無需通過class Hello(object)...的定義:
>>> def fn(self, name='world'): # 先定義函數... print('Hello, %s.' % name)...>>> Hello = type('Hello', (object,), dict(hello=fn)) # 創建Hello class>>> h = Hello()>>> h.hello()Hello, world.>>> print(type(Hello))<type 'type'>>>> print(type(h))<class '__main__.Hello'>
要創建一個class對象,type()函數依次傳入3個參數:
通過type()函數創建的類和直接寫class是完全一樣的,因為Python解釋器遇到class定義時,僅僅是掃描一下class定義的語法,然后調用type()函數創建出class。
正常情況下,我們都用class Xxx...來定義類,但是,type()函數也允許我們動態創建出類來,也就是說,動態語言本身支持運行期動態創建類,這和靜態語言有非常大的不同,要在靜態語言運行期創建類,必須構造源代碼字符串再調用編譯器,或者借助一些工具生成字節碼實現,本質上都是動態編譯,會非常復雜。
metaclass
除了使用type()動態創建類以外,要控制類的創建行為,還可以使用metaclass。
metaclass,直譯為元類,簡單的解釋就是:
當我們定義了類以后,就可以根據這個類創建出實例,所以:先定義類,然后創建實例。
但是如果我們想創建出類呢?那就必須根據metaclass創建出類,所以:先定義metaclass,然后創建類。
新聞熱點
疑難解答