2016-04-12 30 views
3

Ich suche nach einer Möglichkeit, eine Methode einer Klasse zu verwenden, die nicht in dieser Klasse definiert, aber dynamisch behandelt wird. Was ich möchte, erreichen, um ein Beispiel zu nehmen, ist vonGibt es in Python eine "Wildcard-Methode"?

class Hello: 
    def aaa(self, msg=""): 
     print("{msg} aaa".format(msg=msg)) 

    def bbb(self, msg=""): 
     print("{msg} bbb".format(msg=msg)) 

if __name__ == "__main__": 
    h = Hello() 
    h.aaa("hello") 
    h.bbb("hello") 

# hello aaa 
# hello bbb 

die Möglichkeit, ohne die Notwendigkeit der Verwendung von aaa und bbb (und anderen) in der Klasse zu bewegen, sie explizit zu definieren. Für das obige Beispiel wäre das eine Konstruktion, die den Namen der verwendeten Methode (z. B. aaa) erhält und entsprechend formatiert.

Mit anderen Worten, eine "Wildcard-Methode", die selbst ihren Namen handhabt und abhängig vom Namen bedingte Aktionen ausführt. In Pseudocode (um das obige Beispiel zu replizieren)

def *wildcard*(self, msg=""): 
    method = __name__which__was__used__to__call__me__ 
    print("{msg} {method}".format(msg=msg, method=method)) 

Ist eine solche Konstruktion möglich?

Antwort

10

Sie konnten die Klasse überlasten __getattr__ Methode:

class Hello: 
    def __getattr__(self, name): 
     def f(msg=""): 
      print("{} {}".format(msg, name)) 
     return f 

if __name__ == "__main__": 
    h = Hello() 
    h.aaa("hello") 
    h.bbb("hello") 

Ergebnis:

hello aaa 
hello bbb 
0

Wenn Sie die Namen der Methoden im Voraus wissen, könnten Sie dies tun, mit einem Dekorateur fügt hinzu, dass alle die Methoden für dich.

from functools import partial 

def glue(f, names=[]): 
    def wrapper(cls): 
     method = getattr(cls,f) 
     for name in names: 
      setattr(cls, name, partial(method,name=name)) 
     return cls 
    return wrapper 

es wie folgt verwendet:

@glue(f = 'wildcard', names = ['aaa', 'bbb']) 
class Hello(): 
    def wildcard(self, msg='', name=''): 
     print("{} {}".format(msg, name)) 

Wenn Sie mit Dekorateure nicht vertraut sind, über die @ Syntax entspricht dies nach der Klassendefinition zu tun:

Hello = glue(f = 'wildcard', names = ['aaa', 'bbb'])(Hello) 
Verwandte Themen