我曾經看過一段python 代碼。就是元類裡面的函數返回了一個類。我百思不得其解。為什麼要這麼做呢?通過調試我終於明白為什麼這麼做了。
>>> class test(type):
... pass
...
>>> class test1(test):
... def fun (cls, count):
... print count
...
>>> class test2(object):
... __metaclass__ = test1
...
>>> t = test2()
>>> t.fun("hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'test2' object has no attribute 'fun'
我們看,test2的執行個體化t不能繼承 元類的屬性。test2是test1的執行個體,不是繼承的關係。如果是繼承的關係,那麼t可以用test1中的方法fun()。這裡因為fun的參數是cls,也就是t本身是個類的時候才能將自己做為第一個參數傳給函數fun(cls,count),那如果想用fun()怎麼辦呢?這就需要在元類裡面增加一個函數,這個函數在test2()執行個體化的時候就返回一個類。這樣執行個體化的t就是個類,那就可以以類的 方式作為fun(cls,count)的第一個參數了。請看下面的方法:
>>> class test1(test):
... def fun (cls, count):
... print count
... def __call__(cls):
... class C(cls):
... print "I am in class C"
... return C
...
>>> class test2(object):
... __metaclass__ = test1
...
>>> t = test2()
I am in class C
>>> t.fun("hello")
hello
這裡增加了一個函數__call__(),因為這個保證了test2被執行個體化的時候,就返回一個類。這裡一開始調用 __call__()的時候,類C的參數是cls = test1, 所以C繼承了test1的所有的方法。t相當於指向了類C,C指向了test1。所以t.fun("hello")得以執行。