把玩
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):2.6 的 abc 是在生成 Class 時即丟出錯誤訊息,而我的用法只能在
File "Command.py", line 44, in
t = TestCmd()
TypeError: Can't instantiate abstract class TestCmd with abstract methods execute
Traceback (most recent call last):執行 execute() 時才丟出錯誤。還是用簡單直覺的方法解決問題吧。
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>







