Funktion zu einem Dictionary adden mit Hilfe von Decorators

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
aaronlyy
User
Beiträge: 2
Registriert: Freitag 18. September 2020, 11:42
Kontaktdaten:

Hallo,
ich möchte Funktionen zu einerm Dictionary hinzufügen mit Hilfe von Decorators:
Ich habe eine Klasse erstellt und dieser eine Funktion hinzugefügt die 'add' heißt.
Nun würde ich diese Funktion gerne als Decorator über eine Funktion schreiben, das die Funktion zu einem Dictionary was in __init__ erstellt wurde hinzugefügt wird.
Der add Funktion/decorator soll dabei der key als Argument übergeben werden.

Ich möchte das es ungefähr so funktioniert wie das routing in Flask, dort wird auch die funktion zu der übergebenen route gemappt:

Code: Alles auswählen

@app.route('/')
def hello_world():
    return 'Hello, World!'
Hier ist mein Code:

Code: Alles auswählen

class App:
def __init__(self):
    self.functions = {}

def add(self, key, func):
    self.functions[key] = func

app = App()

@app.add("hello")
def print_hello():
    print("hello")
Hier ist der Error:

Code: Alles auswählen

@app.function("hello")
TypeError: function() missing 1 required positional argument: 'func'
Hier ist ein funktionierender Code bei dem die Funktion nur zu einer Liste hinzugefügt wird:

Code: Alles auswählen

class App:
def __init__(self):
    self.functions = []

def add(self, func):
    self.functions.append(func)

def loop_functions(self):
    for f in self.functions:
        f()

app = App()

@app.add
def print_hello():
    print("hello")

app.loop_functions()
Danke :)
narpfel
User
Beiträge: 691
Registriert: Freitag 20. Oktober 2017, 16:10

Moin,

Code: Alles auswählen

@foo
def bar():
    ...
ist das gleiche wie

Code: Alles auswählen

def bar():
    ...

bar = foo(bar)
Deshalb funktioniert das zweite Beispiel. Wenn im Decorator ein Aufruf steht, verändert sich nicht magisch die Semantik:

Code: Alles auswählen

@foo()
def bar():
    ...
wird zu

Code: Alles auswählen

def bar():
    ...

bar = foo()(bar)
entzuckert.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Solche Pattern löst man üblicherweise mit verschachtelten Funktionen. Add braucht noch einen Rückgabewerte, die dekorierte Funktion:

Code: Alles auswählen

class App:
    def __init__(self):
        self.functions = {}

    def add(self, key):
        def inner(func):
            self.functions[key] = func
            return func
        return inner

app = App()

@app.add("hello")
def print_hello():
    print("hello")
Antworten