2017-05-31 3 views
1

Ich möchte 2 Schichten App erstellen, mit App-Logik in einer Klasse und Business in der zweiten Klasse. Und was ich versuche, so etwas wie dies zu erreichen ist:Decorators in Klasse

# app_logic.py 
class AppLogic(object): 
    """docstring for AppLogic""" 
    def __init__(self, arg): 
     super(AppLogic, self).__init__() 
     self.output = open('log.txt', 'w') 

    def log_decorator(f): 
     def wrapper(self, *args, **kwargs): 
      self.output.write(f, ' was called') 
      return f(*args, **kwargs) 
     return wrapper 


# bus_logic.py 
from app_logic import AppLogic 

class BusinessLogic(AppLogic): 
    """docstring for BusinessLogic""" 
    def __init__(self, arg): 
     super(BusinessLogic, self).__init__() 

    @AppLogic.log_decorator 
    def function(self, arg0): 
     # complex magic 
     return 

Aber hier ist ein kleines Problem, wenn ich tox laufen mit py.test für python2.7, heißt es, dass log_decorator ungebunden ist. Ich denke, dass diese Beispielarchitektur vereinfacht werden kann, aber ich weiß nicht wie.

UPDATE

ich damit endete haben:

# utils.py 
plugin_manager_singleton = PManagerSingelton() 

def log(f): 
    def w(self, *args, **kwargs): 
     plugin_manager.call_log(f) 
     return f(*args, **kwargs) 
    return w 

# bus_logic.py 
from utils import log, plugin_manager_singleton 

class App(object): 
    """docstring for App""" 

    def __init__(self, arg): 
     super(App, self).__init__() 
     self.arg = arg 

    @log 
    def sensetive_method(self, arg): 
     special_log_plugin = plugin_manager_singleton.get('special_log') 
     # complex magic 
     return 

komplexe Denken Sie nicht kompliziert.

+0

Ja, 'AppLogic.log_decorator' ist eine ungebundene Methode. Warum hast du es überhaupt in eine Klasse * gebracht? Es ist nur eine Funktion und verwendet nicht den Status 'AppLogic'. –

+0

Es kann tatsächlich in AppLogic-spezifische Ausgabeströme protokolliert werden, und ich muss andere App-Logik wie Benachrichtigungen oder Abfangen von Ausnahmen erstellen. Ich werde mein Beispiel aktualisieren. –

+1

Dann mach entweder eine 'Klassenmethode' (und akzeptiere ein' cls' Argument, also hast du jetzt einen Kontext) oder eine 'statische Methode' (an diesem Punkt werde ich immer noch fragen, warum es überhaupt in deiner Klasse ist). –

Antwort

0

Sie irren sich bei der Definition von Klassenmethoden. Wenn Sie log_decorator als Klassenmethode verwenden möchten, können Sie self nicht verwenden.

class AppLogic(object): 

    log = 'log.txt' 

    @classmethod 
    def log_decorator(cls, f): 
     def wrapper(self, *args, **kwargs): 
      with open(cls.log, 'w') as fp: 
       fp.write(f, ' was called') 
      return f(*args, **kwargs) 
     return wrapper 
+0

Danke, aber dieser Code-Stil ist zu kompliziert. Ich habe meine Architektur vereinfacht, und jetzt ist es klar. Ich brauche keine zwei Schichten, utils Stil ist wirklich genug. –

Verwandte Themen