深奧的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的世界是這樣大,實在有太多有趣的地方可以去玩玩看:)

Post a Comment