2016-05-31 82 views
0

我想只有一个条件执行代码执行只能在类代码:当类内代码执行一个从类AI继承。Python3 - 通过decorator-继承

我希望能有输出是以下内容:

In [1]: import maintenance 
In [2]: a = maintenance.A() 
In [3]: a() 
Out[3]: Stopping A 
     Executing the common task 
     Cleaning logs 
In [4]: b = maintenance.B() 
In [5]: b() 
Out[5]: Stopping B 
     Executing the common task 

的代码如下:

# module maintenance 

1  from functools import wraps 
2 

到由A要执行的代码:

3  def cleaning_logs(): 
4   print("Cleaning logs") 
5 

为了不触摸A级,我创建了一个装饰器:

6  def archive_log(func): 
7   @wraps(func) 
8   def enhanced_func(*args, **kwargs): 
9    func(*args,**kwargs) 
10    cleaning_logs() 
11   return enhanced_func 
12 

因为我认为不可能从上面的装饰器中检索类的信息,所以我试图创建一个类装饰器。下面的代码是不完整的,因为这里是我的问题:

13  def cls_archive_log(cls): 
14   #... Missing Code : I have tried many things 
15   #... Missing Code : I have tried many things 
16   setattr(cls, '__call__', archive_log) 
17   return cls 
18 

,我使用下面的代码这个类装饰:

19  @cls_archive_log 
20  class AI(object): 
21   def __call__(self): 
22    self.stop() 
23    print("Executing the common task") 
24 
25  class A(AI): 
26   def stop(self): 
27    print('Stopping A') 
28 
29  class B(AI): 
30   def stop(self): 
31    print('Stopping B') 
32 

不过说真的,我已经试过了类装饰尽我所能。

任何想法,我怎么可能通过装饰解决我的问题,好吗?

回答

0

每一个简单。只需设置属性如下:

16 def maintenance(cls):                                                              
17  setattr(cls, '__call__', archive_logs(cls.__call__))                                                      
18  return cls 

和装饰需要执行维护

31 @maintenance                                                                 
32 class A(AI):                                                                 
33  def stop(self):                                                               
34   print("Stopping A") 

类的完整代码如下:

#!/usr/bin/env python                                                              

from abc import ABCMeta, abstractmethod                                                          
from functools import wraps                                                             

def cleaning_logs():                                                               
    print("Cleaning logs")                                                             

def archive_logs(func):                                                              
    @wraps(func)                                                                
    def enhanced_func(*args, **kwargs):                                                          
     func(*args, **kwargs)                                                            
     cleaning_logs()                                                              
    return enhanced_func                                                              

def maintenance(cls):                                                              
    setattr(cls, '__call__', archive_logs(cls.__call__))                                                      
    return cls                                                                

class AI(object):                                                               
    __metaclass__ = ABCMeta                                                             

    @abstractmethod                                                               
    def stop():                                                                
     raise NotImplemtedError('NotImplemtedError')                                                       

    def __call__(self):                                                              
     self.stop()                                                               
     print("Executing the common AI task")                                                        

@maintenance                                                                 
class A(AI):                                                                 
    def stop(self):                                                               
     print("Stopping A")                                                             

class B(AI):                                                                 
    def stop(self):                                                               
     print("Stopping B")