把玩 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() 時才丟出錯誤。還是用簡單直覺的方法解決問題吧。