python中有乙個有趣的語法,只要定義型別的時候,實現__call__函式,這個型別就成為可呼叫的。
換句話說,我們可以把這個型別的物件當作函式來使用,相當於過載了括號運算子。
例如,現在我們要計算重力環境下的自然落體位移。我們知道sy=(gt**2)/2,那麼,我們可以建立乙個函式:
def g_dpm(t):
return (9.8*t**2)/2我們都知道,地球表面的重力加速度約等於9.8m/s**2,這個函式實在沒什麼技術含量。
慢,頭兒說了,我要算的是火星啊¥%#!
呃……你能說人家無理取鬧麼?ea的fifa足球裡,我還見過微重力模式的球場,總之,在電腦程式裡,很多超現實的需求都有可能。
恩,最簡單的辦法當然是:
def mar_g_dpm(t):
return (3.92*t**2)/2 #火星表面的重力加速度約等於地球表面的2/5不過,你真的能保證下次那個可愛的策劃不會再設計乙個金星場景?或者木星?或者該死的大魔導師行會開始**新的魔法卷軸——重力操控?
當然,我們可以這樣設計這個函式:
def g_dpm(g, t):
return (g*t**2)/2但是g相對於t,是乙個穩定得多的數量,基本上,在一次相關運算中,g可以當作常量。那麼,乙個可呼叫物件也許更適合。下面定義這樣乙個型別:
class g_dpm(object):
def __init__(self, g):def __call__(self, t):self.g = g
return (self.g*t**2)/2
計算地球場景的時候,我們就可以令e_dpm = g_dpm(9.8),s = e_dpm(t)。同樣的方式,可以很容易的生成其他重力環境下的自由落地公式。
command是gof的《設計模式》中23種設計模式之一。簡單來說,就是把行為物件化,這個過程在python中是很自然的——python裡的函式本來就是一種物件麼。如果只是傳遞函式物件,用不著c/c++中膽戰心驚的函式指標或boost那樣華麗的仿函式型別——這倒不是說python就比c/c++好,設計目標不同。如果需要更複雜的command,我們就要用到**物件了。
事件(event)是framework中常用的設計,通常來講,事件應該滿足以下的要求:
1、有預設行為,如果沒有任何事件響應,至少保證事件發生時不會有錯誤,通常這時什麼也不做。
2、允許為乙個事件註冊多個實現,這個倒不是必須的,但是常見的framework都實現了這一功能。
3、可以登出事件響應,這個就需要第一和第二點的支援。
4、針對不同的事件,可以傳入對應的引數,通常這個功能是通過乙個object *或void *之類的指標(物件引用)傳入乙個結構體來實現的。
在.net中為了支援這個功能,專門定製了乙個特殊型別——delegate,它對應c#的關鍵字delegate。在python中麼……這個東西其實很容易實現,事實上,我就在我的程式中使用了下面的**:
class delegate(set):
def __call__(self, *arg)for foo in self:
foo(*arg)
簡單吧,利用引數列表,我們還很容的實現了不同事件可能的引數定義要求。當然,這與通常見到的event(sender, args)形式並不衝突。其實,更進一步的話,我們要實現併發響應也很容易:
import thread
class mtdelegate(set):
def __call__(self, *args)
for foo in sender:
thread.start_new_thread(foo, args)
我們還可以讓它返回事件響應值的乙個序列:
class fundelegate(set):
def __call__(self, *arg)
return [foo(*arg) for foo in self]
__call__是乙個簡單而有趣的功能,利用它,我們可以更靈活的設計**。當然,過載運算子(從c++的觀點來看,這裡是過載了括號)總是存在乙個風險——它太過有趣,所以容易被濫用。在使用之前,我們最好確認,這個功能用在這裡,確實有助於我們的工作,而不是畫蛇添足。
python 可呼叫物件
compile函式允許程式設計師在執行時刻迅速生成 物件,然後就可以用exec語句或者內建函式eval 來執行這些物件或者對它們進行求值。乙個很重要的觀點是 exec和eval者可以執行字串格式的python 這也是與c 等靜態語言最重要的區別。compile的三個引數都是必須的,第一引數代表了要編...
python 可呼叫物件
compile函式允許程式設計師在執行時刻迅速生成 物件,然後就可以用exec語句或者內建函式eval 來執行這些物件或者對它們進行求值。乙個很重要的觀點是 exec和eval者可以執行字串格式的python 這也是與c 等靜態語言最重要的區別。compile的三個引數都是必須的,第一引數代表了要編...
python的可呼叫物件
這篇文章 定義 call 使乙個類成為可呼叫,相當於過載了 class g dpm object def init self,g self.g g def call self,t return self.g t 2 2 甚至可以這樣使用 print g dpm 9.8 2 g dpm 9.8 相當於...