2017-06-16 5 views
1

Ich versuche, einen access_rights Decorator zu meiner Flasche App hinzufügen, um Berechtigungen beim Zugriff auf eine Route zu überprüfen. Es wird jedoch nicht die Argumente der verzierten Funktion erhalten, was zu einem Fehler führt, wenn ich meine dekorierte Funktion erneut aufrufen möchte.Decorator bekommt keine Argumente

Hier ist ein Beispiel von Code mit dem Dekorateur:

@route('/users') 
@access_rights({'POST': ['admin']}) 
def users(user): 
    pass 

Der user Parameter stammt aus einer Flasche Plugin Ich schrieb, dass der Benutzer die mit der Anfrage übergeben Token erhält. Dies ist meine aktuelle Dekorateur:

def access_rights(permissions): 
    def decorator(f):  
     def wrapper(*args, **kwargs): 
      # Check permissions rights here (not implemented yet) 

      return f(*args, **kwargs) 

     return wrapper 

    return decorator 

Damit ich TypeError: users() takes exactly 1 argument (0 given) wenn ein GET /users tun, was bedeutet, args und kwargs waren beide leer. Allerdings, wenn ich den Dekorateur wie folgt ändern, es funktioniert:

def access_rights(permissions): 
    def decorator(f): 
     return f 

    return decorator 

Ich habe nicht mit Dekorateure viel gearbeitet, aber aus meinem Verständnis, beide Implementierungen oben sollte die users Funktion mit seiner ursprünglichen Parameter aufrufen, noch für aus irgendeinem Grund erhält der erste die Parameter nicht. Warum das?

+1

Dieser Code funktioniert für mich. Wenn Ihre zweite Decorator-Syntax funktioniert, dann bedeutet das, dass Sie sie nicht mit Argumenten verwenden: dh Sie tun nur '@ access_rights' und nicht' @access_rights (was auch immer) '. –

+0

Vielleicht ist irgendwo der Name der Funktionen überprüft? In diesem Fall sollte ein '@ functools.wraps (f)' über dem Wrapper helfen. – Artyer

+0

Verwenden Sie Py2 oder Py3? Ich glaube nicht, dass es einen großen Unterschied macht, aber ich bin neugierig. –

Antwort

0

Ihr Routen-Handler, Funktion users, erwartet einen Parameter.

Aber Ihre Dekorateurin, access_rights, die Sie um users wickeln, übergibt keine user param; Es gibt nur irgendwelche Params weiter, die es empfangen hat (und in diesem Fall gibt es keine, daher der "0" -Teil der Fehlermeldung).

Ein Beispiel soll helfen, zu klären. Hier ist eine kleine, aber komplette Arbeits App, basierend auf dem ursprünglichen Code:

from bottle import route, Bottle 

app = Bottle() 

def access_rights(permissions): 
    def decorator(f): 
     def wrapper(*args, **kwargs): 
      # Check permissions rights here (not implemented yet) 

      the_user = 'ron' # hard-coded for this example 

      return f(the_user, *args, **kwargs) 

     return wrapper 

    return decorator 


@app.route('/users') 
@access_rights({'POST': ['admin']}) 
def users(user): 
    return ['hello, {}'.format(user)] 


app.run(host='127.0.0.1', port=8080, debug=True) 

Beachten Sie, dass die einzige wesentliche Änderung, die ich machte, war eigentlich zu haben access_rights einen Benutzer param passieren auf der ganzen Linie. (Wie es den Benutzer bestimmt, liegt natürlich bei Ihnen - vermutlich ist es der "noch nicht implementierte" Teil, den Sie in Ihrem Kommentar genannt haben).

Hoffe, dass hilft!

+0

Ich verstehe auf jeden Fall, dass der 'user' Parameter nicht übergeben wird, aber das ist nicht die Arbeit meines Dekorateurs. Wie in meiner Frage erwähnt, wird dieser 'user' Parameter generiert und von einem Plugin übergeben, also sollte er nicht vom Decorator behandelt werden. Was für mich keinen Sinn ergibt, ist, dass das direkte Zurückgeben von 'f' anstelle des' wrappers', der nur 'f' mit den übergebenen Argumenten aufruft, nicht zum selben Ergebnis führt. Was fehlt mir hier? – PLPeeters

Verwandte Themen