Differences between revisions 3 and 5 (spanning 2 versions)
Revision 3 as of 2005-06-28 05:56:17
Size: 2429
Editor: LiJie
Comment:
Revision 5 as of 2005-06-28 06:45:26
Size: 2862
Editor: limodou
Comment:
Deletions are marked like this. Additions are marked like this.
Line 63: Line 63:
     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
    assert f3(10, 11) == 10**11
    print '======== test delegate.__call__ with empty exception (empty)'
    f4 = delegate (emptyExcept=True)
    try:
Line 73: Line 68:
    except RuntimeError, ex:
        print 'Exception:', ex
    print '======== test delegate.__call__ with empty exception (not empty)'
    f4 += a
    f4 (3, 5)
Line 74: Line 74:


----

 * 不太清楚这个功能的具体实用性。在NewEdit中有类似的处理,它用来处理代码的插入点。不过有两种处理方式:一种是链式执行,不需要考虑返回值的,可以执行多个函数。一种是中断式执行,即要判断返回值,如果返回值为真,则不再继续执行,并且这个返回值要返回给调用者。因此前面的方式有些象过程,后面则是一个函数式的调用。 -- ["limodou"]

完成了一般的委托功能,一个委托上挂多个函数,可以设置函数列表为空时,是否抛出异常。返回值是函数列表中最后一个函数调用的返回,使用方法可参见test部分。

   1 class delegate:
   2     def __init__(self, *calls, **opts):
   3         for call in calls:
   4             if not callable(call):
   5                 raise RuntimeError, str(call) + ' not a callable object'
   6         self.calls = () + calls
   7         self.emptyExcept = opts.get('emptyExcept', False)
   8     def __call__(self, *args):
   9         if self.emptyExcept and not self.calls:
  10             raise RuntimeError, 'No callable objects'
  11 
  12         try:
  13             result = None
  14             for call in self.calls:
  15                 result = call (*args)
  16             return result
  17         except TypeError:
  18             raise RuntimeError, 'Invalid callable type: ' + str(call)
  19 
  20     def __add__(self, call):
  21         if not callable(call):
  22             raise RuntimeError, str(call) + ' not a callable object'
  23         return delegate(*(self.calls + (call,)))
  24     def __iadd__(self, *calls):
  25         self.calls += calls
  26         return self
  27 
  28 
  29 if __name__ == '__main__':
  30     def a(v1, v2):
  31         print 'a:', v1, v2
  32     def b(v1, v2):
  33         print 'b:', v1, v2
  34     def c(v1, v2):
  35         print 'c:', v1, v2
  36 
  37     class Test:
  38         def hello(self, v1, v2):
  39             print 'Test.hello:', v1, v2
  40 
  41     class Test1:
  42         def __call__(self, v1, v2):
  43             print 'Test1.__call__:', v1, v2
  44 
  45     print '======== test delegate.__init__ and delegate.__call__'
  46     f = delegate(a, b, c, Test().hello, Test1())
  47     f (3, 4)
  48     print '======== test delegate.__add__'
  49     f1 = f + a
  50     f1 (5, 6)
  51     print '======== test delegate.__iadd__'
  52     f2 = delegate(a, b)
  53     f2 += c
  54     f2 (9, 10)
  55     print '======== test delegate.__call__ return value'
  56     f3 = delegate(lambda x, y: x*y)
  57     assert f3(10, 11) == 10*11
  58     f3 = delegate(lambda x, y: x*y, lambda x, y: x**y)
  59     assert f3(10, 11) == 10**11
  60     print '======== test delegate.__call__ with empty exception (empty)'
  61     f4 = delegate (emptyExcept=True)
  62     try:
  63         f4 (3, 5)
  64     except RuntimeError, ex:
  65         print 'Exception:', ex
  66     print '======== test delegate.__call__ with empty exception (not empty)'
  67     f4 += a
  68     f4 (3, 5)


  • 不太清楚这个功能的具体实用性。在NewEdit中有类似的处理,它用来处理代码的插入点。不过有两种处理方式:一种是链式执行,不需要考虑返回值的,可以执行多个函数。一种是中断式执行,即要判断返回值,如果返回值为真,则不再继续执行,并且这个返回值要返回给调用者。因此前面的方式有些象过程,后面则是一个函数式的调用。 -- ["limodou"]

PythonDelegate (last edited 2009-12-25 07:09:16 by localhost)