2016-05-31 17 views
0

Ich versuche, einen Code nur in einer Bedingung auszuführen: wenn der Code innerhalb der Klasse A ausgeführt wird, die von Klasse AI erben.Python3 - Code nur über Klasse durch Decorator- Vererbung ausführen

Der Ausgang Ich wünschte, ich hätte ist die folgende:

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 

Der Kodex ist folgendes:

# module maintenance 

1  from functools import wraps 
2 

Der Code von A ausgeführt werden soll:

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

Um die Klasse A nicht zu berühren, habe ich einen Dekorateur erstellt:

Weil ich denke, dass es nicht möglich ist, die Informationen der Klasse vom obigen Dekorator abzurufen, habe ich versucht, einen Klassendekorator zu erstellen. Der Code unten ist unvollständig, weil hier mein Problem ist:

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 

Diese Klasse Dekorateur, die ich im folgenden Code verwende:

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 

Aber wirklich, ich habe alles versucht, ich für die Klasse Dekorateur konnte .

Irgendeine Idee, wie ich mein Problem durch einen Dekorateur bitte lösen könnte?

Antwort

0

Jeder einfach. Setzen Sie einfach das Attribut wie folgt:

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

Und die Klasse schmücken, die die Wartung

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

Der vollständige Code ist unten implementieren müssen:

#!/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")