完成了一般的委托功能,一个委托上挂多个函数,可以设置函数列表为空时,是否抛出异常。返回值是函数列表中最后一个函数调用的返回,使用方法可参见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)