2016-05-31 2 views
0

코드를 하나의 조건, 즉 클래스 AI에서 상속 한 클래스 A 내에서 실행하면 코드를 실행하려고합니다.Python3 - 데코레이터 상속을 통해 클래스에만 코드 실행

내가 가질 수 있으면 좋겠다 출력은 다음

# module maintenance 

1  from functools import wraps 
2 

(A)에 의해 실행되는 코드입니다 :

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 

코드는 다음과 같다

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")