深奧的Python
April 24, 2008 – 1:58 pm最近在計畫編寫一個Assets Management Tools,所以在想這樣的工具,最好的編寫工具是什麼。我理想中的結構是由多個不同的工具所組成,其中之一個是Web介面。
所以就試用了一下Django,跟了它的幾個example寫了一下。實在是設計得很好。由其是它的MTV(Model-Template-View)式的設計,實在夠方便。
但是有一點,是我完全不明白它是如何做得到的:
1 2 3 4 5 6 7 8 9 10 | from django.db import models # Create your models here. class Publisher(models.Model): name = models.CharField(maxlength=30) address = models.CharField(maxlength=50) city = models.CharField(maxlength=60) state_province = models.CharField(maxlength=30) country = models.CharField(maxlength=50) website = models.URLField() |
這個是Models.py 中定義的Model,django會自動找出所有在這裡被定義的class,再把它們變成相對應的SQL statements,之後把它們create 出來。
我不明白的是,它怎麼能自動找出來呢???我最多只是import 了這個py 檔案,但又沒有把每個class instantiate 出來…
要知道,只好用最後一招,看source code!!!經過一番找尋,終於搞明白了,它用了一個C++ coder 不會用到的meta-programming 的技巧:
1 2 3 4 5 6 7 8 9 | class ModelBase(type): def __new__(cls): .... ..... return register_model(cls); class Model(object): __metaclass__ = ModelBase |
在這裡,__metaclass__是指Model的meta class。
那原本Model的Meta class 是什麼呢? Model 是一個type,所以就是type 啦。
上面的代碼,就是把Model 的Meta Class override,之後定義了一個__new__的方法,當每次Create這個metaclass是也會被call,就在這個時候,register_model就會把這個class 存起。
那什麼時候,這個metaclass 會被Create 呢??就是在定義它自己,和它的sub class時。留意,是定義時,所以當python import 了models.py 時,它就會create Publisher這個Class (是Class,不是Instance),由於Publisher 是Model的sub class,所以,ModelBase 這個metaclass 就被Create了。
有點頭昏了,對嗎??我看到這裡,真的覺得,Python 的 Meta-Programming真的很強大,強大得也太深奧了,怎麼可以一時三刻理解呢???不過也証明coding的世界是這樣大,實在有太多有趣的地方可以去玩玩看:)