Python的延迟绑定

参考:http://stackoverflow.com/questions/2731111/python-lambdas-and-variable-bindings/2731175#2731175

代码:

1. 延迟绑定

class LateBindCounter(object):                                                                                             
    def __init__(self):                                                                                                    
        self.func_map = {}                                                                                                 
        self.setitem = setitem                                                                                             
        for i, key in enumerate([(0, 0), (0, 1), (1, 0), (1, 1)]):                                                         
            self.func_map[key] = lambda x: setitem(x, i, x[i]+1)                                                           
                                                                                                                           
    def calc(self):                                                                                                        
        count = [0, 0, 0, 0, 0]                                                                                            
        for k in (                                                                                                         
                    (0, 1),                                                                                                
                    (1, 0),                                                                                                
                    (2, 3),                                                                                                
                    (4, 5),                                                                                                
                    (1, 0),                                                                                                
                    (0, 0)                                                                                                 
                ):                                                                                                         
            inc_func = self.func_map.get(k, lambda x: setitem(x, -1, x[-1]+1))                                             
            inc_func(count)                                                                                                
        print count 

2. 默认值

class LateBindDefaultValueCounter(object):                                                                                 
    def __init__(self):                                                                                                    
        self.func_map = {}                                                                                                 
        self.setitem = setitem                                                                                             
        for i, key in enumerate([(0, 0), (0, 1), (1, 0), (1, 1)]):                                                         
            self.func_map[key] = lambda x, i=i: setitem(x, i, x[i]+1)                                                      
                                                                                                                           
    def calc(self):                                                                                                        
        count = [0, 0, 0, 0, 0]                                                                                            
        for k in (                                                                                                         
                    (0, 1),                                                                                                
                    (1, 0),                                                                                                
                    (2, 3),                                                                                                
                    (4, 5),                                                                                                
                    (1, 0),                                                                                                
                    (0, 0)                                                                                              
                ):                                                                                                      
            inc_func = self.func_map.get(k, lambda x: setitem(x, -1, x[-1]+1))                                          
            inc_func(count)                                                                                             
        print count

3. exec

class Counter(object):                                                                                                  
    def __init__(self):                                                                                                 
        self.func_map = {}                                                                                              
        self.setitem = setitem                                                                                          
        for i, key in enumerate([(0, 0), (0, 1), (1, 0), (1, 1)]):                                                      
            exec 'func_map[%s] = lambda x: setitem(x, %s, x[%s]+1)' % (key, i, i) in self.__dict__                      
                                                                                                                        
    def calc(self):                                                                                                     
        count = [0, 0, 0, 0, 0]                                                                                         
        for k in (                                                                                                      
                    (0, 1),                                                                                             
                    (1, 0),                                                                                             
                    (2, 3),                                                                                             
                    (4, 5),                                                                                             
                    (1, 0),                                                                                             
                    (0, 0)                                                                                              
                ):                                                                                                      
            inc_func = self.func_map.get(k, lambda x: setitem(x, -1, x[-1]+1))                                          
            inc_func(count)                                                                                             
        print count 

4. 测试及结果

if __name__ == '__main__':                                                                                              
    c = Counter()                                                                                                       
    c.calc() # [1, 1, 2, 0, 2]                                                                                                          
                                                                                                                        
    lb = LateBindCounter()                                                                                              
    lb.calc() # [0, 0, 0, 4, 2]                                                                                                           
                                                                                                                        
    lbd = LateBindDefaultValueCounter()                                                                                 
    lbd.calc() # [1, 1, 2, 0, 2]                                                                                                        

 

posted @ 2013-05-07 22:46  Jimmy N. L.  阅读(565)  评论(0编辑  收藏  举报