python 类方法__call__拦截调用实例介绍

python类,如果定义了__call__方法,

定义类型的时候,实现__call__函数,这个类型就成为可调用的。

换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符。

会为实例应用函数调用表达式运行__call__方法,好处是:

可以让类实例的外观和用法类似于函数。

可编写遵循所需要的函数来调用接口对象,同时又能够保留状态信息。

 

实例1:

 1 class temp:
 2      def __init__(self, data):
 3          self.data = data
 4      def __call__(self, other):
 5          return self.data * other
 6  
 7  ins1 = temp(3)
 8  print ins1.data
 9  3
10  print ins1(5)
11  15
12  
13  class temp:
14      def __init__(self, data):
15          self.data = data
16      def __call__(self, other):
17          return self.data(other) * other
18  
19  ins2 = temp(lambda x:x+1)
20  ins2.data
21  <function __main__.<lambda>>
22  ins2(3)
23  12

 

实例2

 1 class temp:
 2      def __init__(self, arg1, arg2):
 3          self.arg1 = arg1
 4          self.arg2 = arg2
 5      def __call__(self, other):
 6          return self.arg1(other)*other, self.arg2(other)*other
 7  
 8  ins = temp(lambda x:x+1, lambda y:y*2)
 9  
10  print ins.arg1
11  <function __main__.<lambda>>
12  
13  print ins.arg2
14  <function __main__.<lambda>>
15  
16  
17  ins(4)
18  (20, 32)

 

实例3

memcached存储实例:

mc.get(key)  从memcached中取key对应的value

mc.set(key, value, timeout)  设置key-vlaue对

User是个用户类

Order是一个订单类

 1 import mc, User, Order                                                         
 2 
 3 class McNum(object):
 4     def __init__(self, get_num, mc_key, timeout):                              
 5         self.get_num = get_num                                                 
 6         self.mc_key = mc_key
 7         self.timeout = timeout                                                 
 8     
 9     def __call__(self, *key):
10         mkey = self.mc_key % '_'.join(map(str, key))                           
11         num = mc.get(mkey)                                                     
12         if num in None:
13             num = self.get_num(*key) or 0
14             mc.set(mkey, num, self.timeout)                                    
15         return num                                                             
16 
17 get_user_name_count_by_state = McNum(
18     lambda state:User.where(state=state).count(),                              
19     'UserNameCountByState:%s'                                                  
20 )                                                                              
21  
22 get_order_count_by_user_id = McNum(
23     lambda user_id:Order.where(user_id=user_id).count(),                       
24     'OrderCountByUserId%s'                                                     
25 )                                                                              
26 
27 if __name__ == "__main__":                                                     
28     state = [1, 2, 3, 4]
29     user_ids = [12232, 23443, 66433, 23356]                                    
30     for i in state:
31         get_user_name_count_by_state(i)                                        
32     for j in user_ids:
33         get_order_count_by_user_id(j) 

 

 实例4

将__call__所要调用的函数至于类外

 1 def _get(self, *key):
 2     mkey = self.key_pattern % key 
 3     result = mc.get(mkey)
 4     if result in None:
 5         return result
 6         
 7 class McNum(object):
 8     def __init__(self, key_pattern):
 9         self.key_pattern = key_pattern
10         
11     __call__ = _get
12 
13 get_user_name_count_by_state = McCacheA(
14     'UserNameCountByState:%s'
15 )   
16     
17     
18 if __name__ == "__main__":
19     state = [1, 2, 3, 4]
20     for i in state:
21         get_user_name_count_by_state(i)

 

 

结论

posted on 2012-05-07 09:50  huhuchen  阅读(962)  评论(0编辑  收藏  举报

导航