Weiß jemand, warum ich eine vorhandene Endpunktfunktion nicht überschreiben kann, wenn ich zwei URL-Regeln wie diese habe?
app.add_url_rule('/',
view_func=Main.as_view('main'),
methods=["GET"])
app.add_url_rule('/<page>/',
view_func=Main.as_view('main'),
methods=["GET"])
Zurück verfolgen:
Traceback (most recent call last):
File "demo.py", line 20, in <module> methods=["GET"])
File ".../python2.6/site-packages/flask/app.py",
line 62, in wrapper_func return f(self, *args, **kwargs)
File ".../python2.6/site-packages/flask/app.py",
line 984, in add_url_rule 'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint
function: main
Antworten:
Ihre Ansichtsnamen müssen eindeutig sein, auch wenn sie auf dieselbe Ansichtsmethode verweisen.
app.add_url_rule('/', view_func=Main.as_view('main'), methods = ['GET']) app.add_url_rule('/<page>/', view_func=Main.as_view('page'), methods = ['GET'])
quelle
.as_view($VIEW_NAME)
sollte als eindeutiger Zeichenfolgenname übergeben werden.Das gleiche Problem trat mir auf, als ich mehr als eine API-Funktion im Modul hatte und versuchte, jede Funktion mit zwei Dekoratoren zu verpacken:
Ich habe dieselbe Ausnahme erhalten, weil ich versucht habe, mehr als eine Funktion mit diesen beiden Dekorateuren zu versehen:
@app.route("/path1") @exception_handler def func1(): pass @app.route("/path2") @exception_handler def func2(): pass
Insbesondere wird verursacht , indem Sie versuchen einige Funktionen mit dem Namen registrieren Wrapper :
def exception_handler(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: error_code = getattr(e, "code", 500) logger.exception("Service exception: %s", e) r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code}) return Response(r, status=error_code, mimetype='application/json') return wrapper
Das Ändern des Namens der Funktion hat es für mich gelöst ( Wrapper .__ name__ = func .__ name__ ):
def exception_handler(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: error_code = getattr(e, "code", 500) logger.exception("Service exception: %s", e) r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code}) return Response(r, status=error_code, mimetype='application/json') # Renaming the function name: wrapper.__name__ = func.__name__ return wrapper
Dann funktionierte das Dekorieren von mehr als einem Endpunkt.
quelle
functools.wraps
, um die Funktion umzubenennen.wrapper.__name__
stattdessen verwendenwrapper.func_name
. Vielleicht ist das ein Unterschied zwischen Python2 und Python3?wrapper.__name__ = func.__name__
vor dem Aufruf von Wrapper löste das Problem.Für Anwender , dass die Verwendung @ app.route ist es besser , das Schlüssel-Argument zu verwenden ,
endpoint
anstatt den Wert von chaning__name__
wie Roei Bahumi angegeben. Sein Beispiel wird sein:@app.route("/path1", endpoint='func1') @exception_handler def func1(): pass @app.route("/path2", endpoint='func2') @exception_handler def func2(): pass
quelle
Bei Flask müssen Sie einem Endpunkt eine einzelne Ansichtsfunktion zuordnen. Sie rufen
Main.as_view('main')
zweimal auf, wodurch zwei verschiedene Funktionen erstellt werden (genau die gleiche Funktionalität, jedoch unterschiedliche Speichersignaturen). Kurzgeschichte, sollten Sie einfach tunmain_view_func = Main.as_view('main') app.add_url_rule('/', view_func=main_view_func, methods=["GET"]) app.add_url_rule('/<page>/', view_func=main_view_func, methods=["GET"])
quelle
Ich möchte nur eine Lösung vom Typ "Vorlage" hinzufügen.
def func_name(f): def wrap(*args, **kwargs): if condition: pass else: whatever you want return f(*args, **kwargs) wrap.__name__ = f.__name__ return wrap
Ich möchte nur einen wirklich interessanten Artikel "Demystifying Decorators" hinzufügen, den ich kürzlich gefunden habe: https://sumit-ghosh.com/articles/demystifying-decorators-python/
quelle
Dies kann auch passieren, wenn Sie auf verschiedenen Routen identische Funktionsnamen haben.
quelle
Wenn Sie der Meinung sind, dass Sie eindeutige Endpunktnamen haben und dieser Fehler dennoch angezeigt wird, liegt wahrscheinlich ein Problem vor . Gleiches war bei mir der Fall.
Dieses Problem tritt bei Flasche 0.10 auf, falls Sie dieselbe Version haben, gehen Sie wie folgt vor, um dies zu beseitigen:
sudo pip uninstall flask sudo pip install flask=0.9
quelle
Es gibt eine Korrektur für das kürzlich eingeführte Flask-Problem Nr. 570 (Flask 0.10), das dazu führt, dass diese Ausnahme ausgelöst wird.
Siehe https://github.com/mitsuhiko/flask/issues/796
Wenn Sie also zu flask / app.py gehen und die 4 Zeilen 948..951 auskommentieren, kann dies hilfreich sein, bis das Problem in einer neuen Version vollständig behoben ist.
Der Unterschied dieser Änderung ist hier: http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1
quelle
Ihre Ansichtsnamen müssen eindeutig sein, auch wenn sie auf dieselbe Ansichtsmethode verweisen, oder Sie können aus functools Import-Wraps hinzufügen und @wraps https://docs.python.org/2/library/functools.html verwenden
quelle
Verwenden Sie stattdessen Kolben 0.9, und verwenden Sie die folgenden Befehle
sudo pip uninstall flask
sudo pip install flask==0.9
quelle
Das Hinzufügen
@wraps(f)
über der Wrapper-Funktion löste mein Problem.def list_ownership(f): @wraps(f) def decorator(*args,**kwargs): return f(args,kwargs) return decorator
quelle