2016-03-20 3 views
0

Wie übergebe ich ein Wörterbuch in eine Python 2.7-Funktion über eine Flask POST-Anfrage aufgerufen, die nicht von der URL abgeleitet (oder über die POST-Anfrage eingehende) aber anderswo in meinem generiert Skript, zPass in dict zu Funktion über Flask aufgerufen

@app.route('/url_route', methods=['POST']) 
def my_function(foo, bar): 
    baz = foo + bar # both are 'internal' variables, e.g. not via POST 

    (do other stuff with inbound data from POST request) 

    return baz, other stuff 

Wenn ich versuche und Trigger my_function über die POST-Anfrage bekomme ich einen Fehler:

my_function() takes exactly 2 arguments (0 given) 

Ich weiß, könnte dies vermeiden, indem sie sowohl global deklarieren, zum Beispiel

def my_function(foo, bar): 
    global foo 
    global bar 

    baz = foo + bar 

Bu habe ich noch andere Alternativen?

+0

Wo sind diese Variablen definiert? – Suever

+3

Das riecht nach schlechtem Design. Können Sie etwas verkleinern und uns sagen, was diese Variablen sind und warum sie außerhalb davon leben? – Suever

+0

Variablen sind Wörterbücher, die anfänglich im globalen Namespace definiert wurden, unmittelbar nachdem 'if name = __main__'. Dieses Skript unterstützt ein HTML-Frontend, über das der Benutzer eine Datendatei hochlädt, auf der mehrere intermediäre analytische Schritte durch mehrere Funktionsaufrufe außerhalb von my_function ausgeführt werden, und dann wird eine Reihe von Ergebnissen über eine POST-Anforderung zurückgegeben.Die Wörterbücher (hier foo und bar) speichern die Eingaben, Ausgaben der Zwischenschritte und die Endergebnisse, die hochgeladen werden. – pniessen

Antwort

1

Wenn es sich um Konstanten handelt, sind IMO-Globals in Ordnung.

Wenn Sie etwas Code ausführen müssen, um die Werte zu generieren, würde ich Methoden definieren (und möglicherweise in einem anderen Modul, wenn sie wiederverwendet werden sollen), die ich von my_function aufrufen kann. Eigentlich könnte man sie sogar für Konstanten mit einer einfachen Funktion abstrahieren.

def foo(): 
    # compute and return value 

def bar(): 
    # compute and return value 

def my_function():  
    baz = foo() + bar() 

Auch der Anwendungskontext in der Flasche könnte für Sie von Nutzen sein, wenn Sie zum Beispiel Cache-Ressourcen wie Datenbankverbindungen will

bearbeiten, nachdem die Kommentare auf die ursprüngliche Frage zu lesen

Sie sollten wahrscheinlich wirklich ein Schlüssel-Wert-Speicher verwenden, sollten Sie vielleicht Kolben-Sitzung auch: https://pythonhosted.org/Flask-Session/ Sonst werden Sie nicht nur Multi-Thread-Probleme bekommen (können Wenn Sie zwei Arbeitsprozesse ausführen, kann eine Anforderung Daten in einem Prozess speichern, aber die nächste Anforderung kann auf einer anderen Anforderung landen.

Wenn Sie wirklich diese nur tun wollen für Prototyping, würde ich Sie zumindest vorschlagen abstrakt der Zugriff auf die Benutzerdaten anstelle des rohen Wörterbuch auszusetzen. Eine einfache Art und Weise ist so etwas wie dieses:

class FooStore(object): 

    FOO = {} 

    @classmethod 
    def get(cls, user_id): 
     return FOO.get(user_id) 

    @classmethod 
    def set(cls, user_id, value): 
     return cls.FOO[user_id] = value 

# Access/set the values 
FooStore.set(1, {'data': 'some user data'}) 
FooStore.get(1) 

Später können Sie auf einfache Weise die Implementierungen von set und get ändern. Zum Beispiel Serialisieren und Speichern nach Redis bzw. Abrufen und Deserialisieren von Redis. Es wird auch ein einfacheres Testen ermöglichen.