完成了一般的委托功能,一个委托上挂多个函数,可以设置函数列表为空时,是否抛出异常。返回值是函数列表中最后一个函数调用的返回,使用方法可参见test部分。
class delegate: def __init__(self, *calls, **opts): for call in calls: if not callable(call): raise RuntimeError, str(call) + ' not a callable object' self.calls = () + calls self.emptyExcept = opts.get('emptyExcept', False) def __call__(self, *args): if self.emptyExcept and not self.calls: raise RuntimeError, 'No callable objects' try: result = None for call in self.calls: result = call (*args) return result except TypeError: raise RuntimeError, 'Invalid callable type: ' + str(call) def __add__(self, call): if not callable(call): raise RuntimeError, str(call) + ' not a callable object' return delegate(*(self.calls + (call,))) def __iadd__(self, *calls): self.calls += calls return self if __name__ == '__main__': def a(v1, v2): print 'a:', v1, v2 def b(v1, v2): print 'b:', v1, v2 def c(v1, v2): print 'c:', v1, v2 class Test: def hello(self, v1, v2): print 'Test.hello:', v1, v2 class Test1: def __call__(self, v1, v2): print 'Test1.__call__:', v1, v2 print '======== test delegate.__init__ and delegate.__call__' f = delegate(a, b, c, Test().hello, Test1()) f (3, 4) print '======== test delegate.__add__' f1 = f + a f1 (5, 6) print '======== test delegate.__iadd__' f2 = delegate(a, b) f2 += c f2 (9, 10) print '======== test delegate.__call__ return value' f3 = delegate(lambda x, y: x*y) assert f3(10, 11) == 10*11 f3 = delegate(lambda x, y: x*y, lambda x, y: x**y) assert f3(10, 11) == 10**11 print '======== test delegate.__call__ with empty exception (empty)' f4 = delegate (emptyExcept=True) try: f4 (3, 5) except RuntimeError, ex: print 'Exception:', ex print '======== test delegate.__call__ with empty exception (not empty)' f4 += a f4 (3, 5)