六月 28, 2011
» building 'sqlalchemy.cprocessors' extension failed on Windows

在 Windows 上 pip install SQLAlchemy 出現 

Traceback (most recent call last):

  File “<string>”, line 1, in <module>

  File “.\build\SQLAlchemy\setup.py”, line 287, in <module>

    “Retrying the build without the C extension now.”

  File “.\build\SQLAlchemy\setup.py”, line 90, in status_msgs

    print(msg)

UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-6: ordinal not in range(128)

的繞道方式:

用編輯器打開 build\SQLAlchemy\setup.py

把這四行註解起來:

    # Extension(‘sqlalchemy.cprocessors’,

    #       sources=[‘lib/sqlalchemy/cextension/processors.c’]),

    # Extension(‘sqlalchemy.cresultproxy’,

    #       sources=[‘lib/sqlalchemy/cextension/resultproxy.c’])

再試著裝一次

pip install SQLAlchemy

即可能解決。

這樣不編 C extension 會影響 SQLAlchemy 在 Windows 上的效能,但我想通常不會認真要用這個 Windows 當作正式發佈的平台。不幸如此?保佑了。

6/29 更新: 

編不起來可能是環境變數 Path 出了問題,可以檢查一下有沒有被什麼套件(類似 Zenxxx Server 之類) 亂加了雙引號。

六月 27, 2011
» PycTW 2011 順利完成!

比預期的精彩、順利,而且熱鬧!感謝許多人客帶來的美食、主辦人 Thinker、各講者與 OpenFoundry 讚助的場地與飲料。

大部份的簡報連結都在 PycTW2011 wiki 上。

我分享的兩個簡報可在 PycTW2011 wiki 或我的 Scribd 上找到。

開始期待了,2012。

六月 20, 2011
» 在 Windows、Linux,以及 Mac 上安裝 pip - Python 套件管理程式

這篇是寫給沒用過 virtualenv 與 pip 的 Python 套件管理攻略。

PycTW 2011 上應該沒時間講這種事,還是先在這邊還攻略債吧。

步驟

先講一下原則上的建議安裝方式(同 pip 官方文件上的建議):利用 virtualenv 內建的 pip

  1. 下載 virtualenv.py
  2. python virtualenv.py [新專案環境目錄名]
  3. 進入 virtualenv 環境(在這個環境下安裝的東西不會影響到整個系統)
  4. 開始使用 pip 安裝套件

 

Linux 或 Mac 上的指令參考

$ curl -O https://raw.github.com/pypa/virtualenv/master/virtualenv.py
$ python virtualenv.py my_new_env
$ . my_new_env/bin/activate
(my_new_env)$ pip install ...

通常這樣就完成了 Linux 與 Mac 上的攻略。

 

Windows 上的指令參考

  1. 儲存那個網頁,命名檔案為 virtualenv.py
  2. 打開 terminal(cmd.exe 之類的),cd 到你要放專案資料夾的地方 (例: cd C:\Users\Keith )
  3. python virtualenv.py my_new_env
  4. my_new_env\Scripts\activate.bat
  5. pip install …

 

附錄

如何使用 pip 安裝一個名為 xxx(bottle, nose, Requests, SQLAlchemy, Pyramid, … 等等) 的套件?

pip install xxx

移除套件? pip uninstall xxx

四月 7, 2011
» Playing Editra v0.6.26 with Python on Windows 7



Playing Editra v0.6.26 with Python on Windows 7

十月 12, 2010
» easy_install -i http://b.pypi.python.org/simple/ -U setuptools

四月 21, 2010
» (又)一個小而美的 Python 網站框架:Flask

荒廢好久的網誌,因有沒有網站開發經驗的人寫信問我關於 Pylons 的問題,特此更新一文。

聲明在先,此文並不是為了回答 Pylons 的問題而寫的,而是分享另一個 Web Framework(是的,又來了)。 

近日聽說了一個看來更小,更簡單而且(表面)也很優雅的 Python 網站框架:Flask

我想對沒有相關經驗的人而言,東西愈小愈容易學習,如果這東西還有良好而成熟的設計,那就更棒了。Flask 正是一個看起來像這樣的東西。在 Python 經歷了 ZopeDjangoTurboGearsPylonsBottle 等等網站框架之後,還是有人另外寫了這個網站框架,我猜……它別有意圖

 不過它意圖在官網也寫得很清楚,就是(另)一個微網站框架(Micro Web Framework)。什麼是「微」(micro)?原諒我忍不住想在這裡簡單地說,就是「很小」(very small)。(給認真魔人的連結:"Flask - Foreword - What does Micro Mean?")

好吧官網上還寫了一些也許有點可口的菜單:

都流口水了。不過不免一提上述的功能 Pylons 也幾乎都內建了。

呃,時光匆匆,我該睡了,最後幾分鐘剛好來裝個網站框站跑個應用程式起來。

安裝:(更詳細的官網安裝說明連結
easy_install Flask

寫一個 Hello 網站應用程式(都這種時候了,當然是從官網上複製過來的):
檔名:hello.py


from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()


跑:
python hello.py

四月 20, 2010
» (又)一個小而美的 Python 網站框架:Flask

荒廢好久的網誌,因有沒有網站開發經驗的人寫信問我關於 Pylons 的問題,特此更新一文。

聲明在先,此文並不是為了回答 Pylons 的問題而寫的,而是分享另一個 Web Framework(是的,又來了)。 

近日聽說了一個看來更小,更簡單而且(表面)也很優雅的 Python 網站框架:Flask

我想對沒有相關經驗的人而言,東西愈小愈容易學習,如果這東西還有良好而成熟的設計,那就更棒了。Flask 正是一個看起來像這樣的東西。在 Python 經歷了 ZopeDjangoTurboGearsPylonsBottle 等等網站框架之後,還是有人另外寫了這個網站框架,我猜……它別有意圖

 不過它意圖在官網也寫得很清楚,就是(另)一個微網站框架(Micro Web Framework)。什麼是「微」(micro)?原諒我忍不住想在這裡簡單地說,就是「很小」(very small)。(給認真魔人的連結:“Flask - Foreword - What does Micro Mean?“)

好吧官網上還寫了一些也許有點可口的菜單:

都流口水了。不過不免一提上述的功能 Pylons 也幾乎都內建了。

呃,時光匆匆,我該睡了,最後幾分鐘剛好來裝個網站框站跑個應用程式起來。

安裝:(更詳細的官網安裝說明連結
easy_install Flask

寫一個 Hello 網站應用程式(都這種時候了,當然是從官網上複製過來的):
檔名:hello.py


from flask import Flask
app = Flask(__name__)


@app.route("/")
def hello():
return "Hello World!"

if __name__ == "__main__":
app.run()


跑:
python hello.py

八月 22, 2009
» 簡單的 python timeit 範例

[更正啟事:此篇測試有誤,更正於]


PTT 文章回收 :)

要測微效能的差異,可考慮 python 內建(總是如此啊)更準確的 timeit 模組

使用方式如:


# encoding: utf8



import timeit



run_test1 = '''

import testit

testit.test1(testit.al, testit.bl)

'''

run_test2 = '''

import testit

testit.test2(testit.al, testit.bl)

'''

run_test3 = '''

import testit

testit.test3(testit.al, testit.bl)

'''



al = []

bl = []

for i in range(1000):

    al.append(i)

    bl.append(999 -i)



def test1(al, bl):

    al = al + bl



def test2(al, bl):

    al.extend(bl)



def test3(al, bl):

    al += bl



if __name__ == '__main__':

    times = 100000

    t1 = timeit.Timer(stmt=run_test1)

    print "%.8f sec/pass" % (t1.timeit(number=times)/times)



    t2 = timeit.Timer(stmt=run_test2)

    print "%.8f sec/pass" % (t2.timeit(number=times)/times)



    t3 = timeit.Timer(stmt=run_test3)

    print "%.8f sec/pass" % (t3.timeit(number=times)/times)



# See also: http://docs.python.org/library/timeit.html



附帶這個測試的 output 作為參考
0.00002528 sec/pass
0.00002075 sec/pass
0.00002029 sec/pass

PS. 就算這麼做,還是要跑第二次之後才比較接近實際上想看到的差異
第一次
% python testit.py
0.00002639 sec/pass
0.00002135 sec/pass
0.00002575 sec/pass

第二次
% python testit.py
0.00002557 sec/pass
0.00002103 sec/pass
0.00001995 sec/pass

第三次
% python testit.py
0.00002528 sec/pass
0.00002075 sec/pass
0.00002029 sec/pass

» 更正:簡單的 python timeit 範例

感謝 ptt python 板友 sbr 指正:

※ 引述《sbrhsieh (sbr)》...
: 依照上述的碼來說,依照 Python 2.5.4 內附的 timeit module 的設計來看,test2
: 與 test3 重複執行多次,會導致 testit module loaded 後 al 參考的 list object
: 一直作串接動作而變長(長度超過 100M)。
: 重複跑 test2 與 test3 會比 test1 多許多記憶體配置與 memory copy 的操作,
: 我不認為你跑出來的量測結果是合理的(test2/test3 應該比 test1 慢上許多)。

原文中的程式碼有如下問題:global is evil XD

先看看原來程式碼的問題,我們加上下面的程式碼:

run_print_len = '''
import sys
import testit
print >> sys.stderr, 'len(al):', len(testit.al), 'len(bl):', len(testit.bl)
'''

...(原來的code)

if __name__ == '__main__':
...(原來的code)

pl = timeit.Timer(run_print_len) # 新增這兩行
pl.timeit(number=1) #

得到

% python2.5 testit.py
0.00002924 sec/pass
0.00002564 sec/pass
0.00002465 sec/pass
len(al): 200001000 len(bl): 1000

可以看到 al list 的長度非常之長,都快跟我一樣長了 XD (誤),因為每次對 testit.al 所作的改變都會繼續被下一個 test 使用。這樣的測試造成 al 在每個 test 的長度都不同,可能造成測試的不準確。
如 sbr 所述,記憶體可能需要重新配置之類的 (不過在我的環境好像沒有影響?)

import timeit



run_test1 = '''

import testit

al, bl = testit.generate_albl()

al = testit.test1(al, bl)

'''

run_test2 = '''

import testit

al, bl = testit.generate_albl()

al = testit.test2(al, bl)

'''

run_test3 = '''

import testit

al, bl = testit.generate_albl()

al = testit.test3(al, bl)

'''



run_print_len = '''

import sys

import testit

al, bl = testit.generate_albl()

print >> sys.stderr, 'len(al):', len(al), 'len(bl):', len(bl)

'''



def generate_albl():

    al = [1]*1000

    bl = [999]*1000

    return al, bl



def test1(al, bl):

    al = al + bl

    return al



def test2(al, bl):

    al.extend(bl)

    return al



def test3(al, bl):

    al += bl

    return al



if __name__ == '__main__':

    times = 100000

    t1 = timeit.Timer(run_test1)

    print "%.8f sec/pass" % (t1.timeit(number=times)/times)



    t2 = timeit.Timer(run_test2)

    print "%.8f sec/pass" % (t2.timeit(number=times)/times)



    t3 = timeit.Timer(run_test3)

    print "%.8f sec/pass" % (t3.timeit(number=times)/times)



    pl = timeit.Timer(run_print_len)

    pl.timeit(number=1)

修正後的結果:
Python 2.5.4 (r254:67917, Dec 23 2008, 14:57:27) 
[GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

% python2.5 testit.py
0.00005440 sec/pass
0.00004385 sec/pass
0.00004388 sec/pass
len(al): 1000 len(bl): 1000

八月 16, 2009
» COSCUP 2009 Lighting Talk 補遺 - 關於軟體開發的敏捷測試

開源人年會2009雖然只是五分鐘,但還是緊張了一下,有些話說得不清楚或亂七八糟,在此望請海涵。

不過聽到聽眾的笑聲還是很開心。雖然很多梗沒講到(測試網頁是否被反山達基),反而跑出一些莫明奇妙的點(對啊)。其它的 Lighting Talks 更是歡樂無比,能一邊跑步一邊講真的是,XD。

先在這裡補一下沒講到的點:

一修改完檔案立刻看到測試結果,概念上說來非常簡單:

檔案有更動->立刻進行測試->回報結果

而實際上 DEMO 時我所使用的程式是:

noscat 'nosetests --with-growl -w sanity/tests' sanity

1. noscat: 進行檔案的監測並執行對應的指令

2. 'nosetests --with-growl -w sanity/tests': 測試並回報結果

3. sanity: 要監視的檔案(或目錄)

關於 2. 的部份,不同的程式或框架有不同的測試回報,如果你未曾試過為程式寫測試碼,那麼也許你根本不需要這種東西,不如來去看場電影實在。但若你對敏捷開發有興趣、對軟體測試有熟悉,或對 debug 五年前未發現的問題記恨在心,那麼你應該試一下測試驅動開發 (Test-Driving Development, TDD)。

不論如何,是一個有趣又有收護又有點頭暈又累的 COSCUP 第一天。

當然,DEMO 用的 (Python, Pylons, nosetests, noscat) 都很巧地是 Open Source。 ;)

另外,我的確在徵友……關於軟體開發方面。若有任何棲息於大台南的 code developer,請知會我一聲吶。都一年了…

六月 17, 2009
» 測試貓 noscat - 但我從沒想養貓啊

最近程式塗著玩著,就生了一隻伯特與一隻貓。

bot 下次聊。丟出這隻貓先。

這隻貓名 noscat,喜歡盯著東西跑。

驅動它的方式是:

python noscat 'nosetests -w app/tests/lib' app/lib app/model ...

這會讓它有如下的反應:

它會先饋集 app/lib 及 app/model (你可以繼續增加) 下面的所有檔案,然後(在 shell 中)跑一次 'nosetests -w app/tests/lib' 這指令。

接著一旦它收集的檔案有所更動,它就會再跑一次那指令。

你可以從這裡下載這隻貓。

For test-driving, you always need a cat.

Update 2009-06-17: 修正所給的路徑並未被確實監視。加入忽略特定副檔名(如*.swp 及 *.pyc)功能。

二月 23, 2009
» Pylons - Web 開發瑞士刀

Pylons - Web 開發瑞士刀.pdf @ scribd
昨天在 Kalug 給的 Topic,經善後的 PDF。請點擊圖片享用。

Update: 投影片可直接在 KaLUG Meeting 上下載,不必登入 scribd.

一月 17, 2009
» Pylons & PycTW2008 圓滿結束之投影片告白

2008 年 6 月 15 日,PycTW2008 正式展開,也正式結束(這不是廢話嗎)。不僅有吃有喝又有玩,還有高手環伴,可以說只差個人來七步吟詩了(誤)。我也在疲勞 的抗奮狀態下,講了 Pylons Session。可惜在準備不足,時間又抓得不夠好,只 demo 了一個 Hello Pylons,應該還有一卡車可以講啊啊!!所以這個故事告訴我們:要早點睡。

最後要感謝 thinker 大力發起與讚助的單位,期待明年的 2009 - Python 大逃殺!?(又誤)

» 在 Google App Engine 1.1.7 上跑 Pylons 0.9.7 RC4

版本資訊:
OS: Ubuntu 8.10
Python 2.5.4
Pylons 0.97rc4
Google App Engine 1.1.7

步驟:

svn checkout http://appengine-monkey.googlecode.com/svn/trunk/ appengine-monkey
python2.5 appengine-boot.py --paste-deploy my-app
## my-app 可改為你的想要的應用程式名稱,如:hellopylons)
>> Enter template_engine (mako/genshi/jinja/etc: Template language) ['mako']:
>> Enter sqlalchemy (True/False: Include SQLAlchemy 0.4 configuration) [False]:
>> Enter google_app_engine (True/False: Setup default appropriate
>> for Google App Engine) [False]:True
cd my-app
source bin/activate
easy_install Pylons
cd src
paster create --template=pylons MyApplication
## MyApplication 依樣可自訂其名稱
cd my-app/src/MyApplication
python setup.py develop
cd ../..
python -m pth_relpath_fixup

編輯 my-app/development.ini:
[app:the-app]
## Change this to whatever you name your application:
use = egg:MyApplication

到此與 appengine-monkey 上差不多,但接著要多幾個動作才能見到 Welcome:

一.
File ".../appengine-monkey/my-app/src/MyApplication/MyApplication/config/environment.py", line 34, in load_environment
module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
KeyError: 'cache_dir'
避免如上錯誤,編輯 my-app/src/MyApplication/config/environment.py,註解掉一行:
        ...
#module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
...

二.
VersionConflict: (WebOb 0.9 (.../google_appengine/lib/webob), Requirement.parse('WebOb>=0.9.4'))
移走 google_appengine/lib/webob 來避免這錯誤:
mv google_appengine/lib/webob/ google_appengine/webob/

即 Google Appengine 1.1.7 隨附的 webob 版本 (0.9) 未達 Pylons 0.9.7 的要求 'WebOb>=0.9.4'
註:如果你有跑其它 App Engine apps,這個 google_appengine 最好單獨就給 Pylons 使用,以免造成其它程式的問題。

好,是時候了:
/usr/bin/python2.5 google_appengine/dev_appserver.py my-app
## 我使用自己 compile 的 /usr/bin/local/python2.5 google_appengine/dev_appserver.py my-app
主要參考:
Appengine-Monkey: http://code.google.com/p/appengine-monkey/wiki/Pylons

註二:
自己 compile 的 Python 要支援 SSL 才能跑 Google App Engine,在 Ubuntu 8.10 下就是裝完 libssl-dev 後重新 make && make install。

十月 6, 2008
» ABCs from Python 2.6 to 2.5

把玩 Command Pattern 時用到的:
# CommandExample.py

try:
  from abc import ABCMeta, abstractmethod
except ImportError, e:
  class ABCMeta(type):
    pass
  def abstractmethod(f):
    def raiseNotImp(f):
      raise NotImplementedError(repr(f))
    return raiseNotImp

class Command(object):
  __metaclass__ = ABCMeta

  @abstractmethod
  def execute(self): pass

class NotImpExeCmd(Command): pass

class ImpExeCmd(Command):
  def execute(self): print "Hi! I'm executed."

def executed_or_error(name, ExeCmdClass):
  try:
    Cmd = ExeCmdClass()
    Cmd.execute()
  except Exception, e:
    print repr(e)
  else:
    print name, 'is executed. Really.'

executed_or_error('Command',      Command      )
executed_or_error('NotImpExeCmd', NotImpExeCmd )
executed_or_error('ImpExeCmd',    ImpExeCmd    )

Demo:
% python2.5 CommandExample.py
NotImplementedError('<__main__.Command object at 0xb7dbf88c>',)
NotImplementedError('<__main__.NotImpExeCmd object at 0xb7dbf8cc>',)
Hi! I'm executed.
ImpExeCmd is executed. Really.

% python2.6 CommandExample.py
TypeError("Can't instantiate abstract class Command with abstract methods execute",)
TypeError("Can't instantiate abstract class NotImpExeCmd with abstract methods execute",)
Hi! I'm executed.
ImpExeCmd is executed. Really.

反證一下,把 @abstractmethod 那行註解掉,用 python2.5 或 2.6 都得到以下結果:
Command is executed. Really.
NotImpExeCmd is executed. Really.
Hi! I'm executed.
ImpExeCmd is executed. Really.

不過最直接的方法呢,就是決定到底要用 2.5 還是 2.6 來寫。(茶)

Update @2008-10-06 :
看來這裡我的 monkey patch 還是沒 2.6 來的漂亮,實際上 trace code 的情況:

Traceback (most recent call last):
File "Command.py", line 44, in
t = TestCmd()
TypeError: Can't instantiate abstract class TestCmd with abstract methods execute
2.6 的 abc 是在生成 Class 時即丟出錯誤訊息,而我的用法只能在
Traceback (most recent call last):
File "Command.py", line 45, in
t.execute()
File "/home/keitheis/Conquer/PySys/abc.py", line 10, in raiseNotImp
raise NotImplementedError(repr(f))
NotImplementedError: <__main__.TestCmd object at 0xb7ce2acc>
執行 execute() 時才丟出錯誤。還是用簡單直覺的方法解決問題吧。

十月 5, 2008
» 打造一個與世隔離的環境: virtualenv & pyinstall

這裡試著簡述如何在*nix下使用 easy_install & virtualenv & pyinstall 來打包工作環境:

*請務必非常小心地對待自己設的 PYTHONPATH 變數,及 .pydistutils.cfg 檔。

首先 easy_install virtualenv (若你還沒這樣做)。目前 virtualenv 最新為 1.3,若非此版,可下 easy_install -U virtualenv 更新。

到要放新環境的資料夾 (此例為 ~/projects),下 virtualenv (給環境一個名稱,此例為 env)
cd ~/projects
virtualenv --no-site-packages env

此時什麼 .pydistutils.cfg 或 PYTHONPATH 等都得清乾淨,若你兩者都沒設就不必管它。
cd ~/projects/env
source bin/activate
easy_install pyinstall
pyinstall.py (...pylons, django ...所有你想要加入新環境的eggs,用法與easy_install類似)

基本上到這就是一般 virtualenv 的用法,只是改用 pyinstall 置換 easy_install。
再來打包整個環境:
pyinstall.py --freeze=env.req (看一下產出的 env.req 跟妳想像中需要裝到的eggs是不是一樣)

pyinstall.py --bundle env.pybundle -r env.req
         ^^^ 為什麼不是 pyinstall?真的很執著…

大功告成。到下一台要佈署的主機上,一樣做 virtualenv env (然後一樣清乾淨PYTHONPATH等變數)
cd env
easy_install pyinstall

把剛剛的 env.pybundle 複製過來,下
pyinstall.py env.pybundle

即可看到這一連串的咒語所施展的魔法。enjoy

Updated: env.bundle 會被 pyinstall 誤認為要下載的 egg,得以 .pybundle 才會被認得。

參考資料:

附上 env.req 在用 pyinstall.py 裝了 Pylons, SQLAlchemy 與 Genshi 後的結果:
Beaker==1.0.2
FormEncode==1.0.1
Genshi==0.5.1
Mako==0.2.2
Paste==1.7.1
PasteDeploy==1.3.2
PasteScript==1.6.3
Pygments==0.11.1
Pylons==0.9.7rc2
Routes==1.10.1
SQLAlchemy==0.5.0rc1
Tempita==0.2
WebError==0.9
WebHelpers==0.6.1
WebOb==0.9.3
decorator==2.3.1
nose==0.10.3
simplejson==2.0.1
wsgiref==0.1.2
*魔蛋圖片為: Tsja! 之 《Heavenly egg》

十月 4, 2008
» What is in the __future__ of Python 2.6?

Python PoweredPython 2.6 (r26:66714, Oct 3 2008, 23:56:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pprint import pprint
>>> import __future__
>>> pprint(dir(__future__))
['CO_FUTURE_ABSOLUTE_IMPORT',
'CO_FUTURE_DIVISION',
'CO_FUTURE_PRINT_FUNCTION',
'CO_FUTURE_UNICODE_LITERALS',
'CO_FUTURE_WITH_STATEMENT',
'CO_GENERATOR_ALLOWED',
'CO_NESTED',
'_Feature',
'__all__',
'__builtins__',
'__doc__',
'__file__',
'__name__',
'__package__',
'absolute_import',
'all_feature_names',
'division',
'generators',
'nested_scopes',
'print_function',
'unicode_literals',
'with_statement']
>>>

不過我是想找ABCs,即使 unicode_literals 很吸引我。

寫著寫著就找到了:What’s New in Python 2.6 - PEP 3119: Abstract Base Classes

九月 1, 2008
» 用 Python 來模擬 Erlang 的 RPC

如此奮鬥了一天,卻未及要害,殘念。


import candygram as cg

def rpc(pid, req, res=[]):
  def receive(fun = cg.Receiver()):
    fun[cg.Any] = lambda m: m, cg.Message
    res.append(fun())
  pid | (cg.spawn(receive), req)
  while( not res): pass
  return res.pop()

def loop():
  fun = cg.Receiver()
  def rect  (( pid, (fun, width, ht) )): pid | width * ht
  def circle(( pid, (fun, R)         )): pid | 3.14159 * R * R
  def other (( pid, (args)           )): pid | ('error', args)
  fun[ cg.Process, ('rect', int, int)] = rect,   cg.Message
  fun[ cg.Process, ('circle', int)   ] = circle, cg.Message
  fun[ cg.Process, cg.Any            ] = other,  cg.Message
  for r in fun: pass

if __name__ == '__main__':
  import time
  proc = cg.spawn(loop)
  print rpc(proc, ('rect', 6, 8))
  print rpc(proc, ('circle', 6))
  print rpc(proc, ('joke'))
  time.sleep(0.2) # Give the proc a chance to print before termination

參閱 "Programming Erlang" Ch8.3 area_server1.erl

六月 11, 2008
» 很忙

我們都很忙。於是 Pylons 提供了一連串叫好的 In A Hurry 系列,給來不及的眾生一個機會?

更忙一點的人,也許需要小抄了: Pylons Cheatsheet

六月 7, 2008
» Pylons 0.9.7 內建支援 SQLAchemy 組態設定

在 Pylons 0.9.7 中已內建支援自動產生對 SQLAchemy 的組態設定,情況大概是這樣:

(virpylons)[k]@XO % PYTHONPATH='' paster create -t pylons sqlarmy
Selected and implied templates:
Pylons#pylons Pylons application template

Variables:
egg: sqlarmy
package: sqlarmy
project: sqlarmy
Enter sqlalchemy (True/False: Include SQLAlchemy 0.4 configuration) [False]: _

嗯,好不容易。其自動化的部分大概如 Working with databases and SQLAlchemy 這一段所示,這是目前在 Pylons 0.9.6 所需要DIY的部份。

附註,因為我設了自己的 PYTHONPATH,如果沒把它清空 (PYTHONPATH=''),跑 paster 指令時裝的 pylons 會在我個人預設的套件位置找到 0.9.6 版,而非我用 go-pylons.py 產生 virtualenv 中的 0.9.7 版,讓我困擾了一小下,怎麼沒有 sqlalchemy 的化學反應?XD

A Feedjack powered Planet
A Django site.