2017-01-15 5 views
-3

ich folgendes zu tun:
Ich habe eine Klasse, und diese Klasse hat eine dict cmds namens. Ich möchte Elemente dynamisch über Dekoratoren hinzufügen. Der Dekorator sollte eine Funktion, eine Methode dieser Klasse sein.
Beispielcode auf, was ich will:Python passieren Klasseninstanz zu seiner Methode (Funktion) Dekorateure

class Foo(object): 
    #In a class: 
    @cmd("exit") 
    def cmd_exit(self, *args): 
     self.run=0 
     print("Exiting mainloop...") 
    @cmd('reconnect') 
    def cmd_reconnect(self): 
     self.connect(self._host) 

Damit das funktioniert, Ich brauche selbst cmd, zu dem Verfahren, das ein Dekorateur ist zu passieren. cmd erhält jedoch keine self.
Also wie kann ich das tun?
EDIT:
My Foo.cmd Methode hat folgende Definition:

def cmd(self, name): 
    def decorator(funcs): 
     fname=name if name else funcs.__name__ 
      self.cmds[fname]=funcs 
      self.cmdLogger.info("Registrated function %s", name) 
      return 
    return decorator 

und die Schnur I zum decorator Pass (zB "exit" und 'Reconnect') anzumerken, dass der innere decorator nur empfangen, (Dekorateur genannt) gibt None zurück, so dass die ursprüngliche Funktion, auf die der Dekorator aufgerufen wurde, "entfernt" ist.

+1

Ihren ersten Codeblockes Unter der Annahme, sollte sein verschachtelt in einem 'Klasse Foo:' Block (das solltest du hinzufügen!): Nicht nur existiert 'selbst' noch nicht, die Klasse selbst existiert noch nicht. Auf der obersten Ebene des Blocks "Klasse" definieren Sie immer noch, was diese Klasse enthalten soll. Natürlich können Sie keine Instanz dieser Klasse haben. – Kevin

+0

@Kevin ... oh @ Đ # đ, das war das Problem. Ich kann eine Methode für eine Methode nicht aufrufen, wenn sie definiert wird. Aber ich kann es später tun, indem ich die 'cmd_'-Funktionen außerhalb der Klasse verschiebe und' Foo.cmd (name) 'darauf anrufe. Ich muss wirklich müde sein, dass ich es übersehen habe. Du solltest eine Antwort schreiben, damit ich sie annehmen kann. – Sasszem

Antwort

1

Sie könnten ‚cmds‘ von einer anderen Klasse erben, in ‚zentralem Ort‘ den Überblick über Ihre Protokolle zu halten:

from functools import wraps 

def cmd(*name): 
    def wrapper(fn): 
     @wraps(fn) 
     def real_decorator(*args, **kw): 
      fname = name[0] if name else fn.__name__ 

      cls = args[0] 
      cls.cmds[fname]=fn 
      #self.cmdLogger.info("Registrated function %s", name) 
      return fn(*args,**kw) 
     return real_decorator 
    return wrapper 

class Logger(object): 
    def __init__(self): 
     self.cmds = {} 
     #self.cmdLogger = ... 

class Foo(Logger): 
    @cmd("exit") 
    def cmd_exit(self, *args): 
     self.run=0 
     print("Exiting mainloop...") 

    @cmd('reconnect') 
    def cmd_reconnect(self): 
     self.connect(self._host) 

f = Foo() 
f.cmd_exit() 
print(f.cmds) 

Returns:

Exiting mainloop... 
{'exit': <function Foo.cmd_exit at 0x7fb11cfee048>} 
Verwandte Themen