如果我有两个这样的网址规则
,有谁知道为什么我不能覆盖现有的端点功能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"])
回溯:
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
答案 0 :(得分:51)
同样的问题发生在我身上,但使用方法不同。当我尝试用2个装饰器包装API函数时:
我得到了同样的异常,因为我试图用这两个装饰器包装多个函数:
@app.route("/path1")
@exception_handler
def func1():
pass
@app.route("/path2")
@exception_handler
def func2():
pass
具体来说,这是因为尝试使用名称包装注册一些函数引起的:
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
更改函数名称为我解决了它( wrapper.func_name = func.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.func_name = func.func_name
return wrapper
然后,装饰多个端点。
答案 1 :(得分:44)
即使视图名称指向相同的视图方法,您的视图名称也必须是唯一的。
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'])
答案 2 :(得分:14)
对于使用@ app.route的用户,最好使用密钥参数endpoint
,而不是像Roei Bahumi那样查看__name__
的值。以他的榜样为例:
@app.route("/path1", endpoint='func1')
@exception_handler
def func1():
pass
@app.route("/path2", endpoint='func2')
@exception_handler
def func2():
pass
答案 3 :(得分:8)
Flask要求您将单个“视图函数”与“端点”相关联。您正在调用Main.as_view('main')
两次,这会创建两个不同的功能(功能完全相同但内存签名不同)。简短的故事,你应该简单地做
main_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"])
答案 4 :(得分:4)
我想在此添加一个更多的模板&#39;类型解决方案。
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
只想添加一篇非常有趣的文章&#34; Demystifying Decorators&#34;我最近发现:https://sumit-ghosh.com/articles/demystifying-decorators-python/
答案 5 :(得分:2)
如果您认为自己拥有唯一的端点名称,但仍然会出现此错误,那么您可能面临issue。我的情况也是如此。
如果你有相同的版本,这个问题是烧瓶0.10,然后按照以下方法去掉:
sudo pip uninstall flask
sudo pip install flask=0.9
答案 6 :(得分:1)
Flask问题#570引入了近期(烧瓶0.10),导致引发此异常。
请参阅https://github.com/mitsuhiko/flask/issues/796
因此,如果你去flask / app.py并注释掉4行948..951,这可能会有所帮助,直到问题在新版本中完全恢复。
这种变化的差异在于:http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1
答案 7 :(得分:0)
即使您的视图名称指向相同的视图方法,也必须是唯一的,或者您可以从functools导入包装中添加并使用@wraps https://docs.python.org/2/library/functools.html
答案 8 :(得分:0)
改为使用烧瓶0.9
使用以下命令
sudo pip uninstall flask
sudo pip install flask==0.9
答案 9 :(得分:0)
当您在不同的路由上具有相同的函数名称时,也会发生这种情况。
答案 10 :(得分:0)
在包装函数上方添加@wraps(f)
解决了我的问题。
def list_ownership(f):
@wraps(f)
def decorator(*args,**kwargs):
return f(args,kwargs)
return decorator
答案 11 :(得分:0)
如果你在python notebook上使用flask,每次修改代码都需要重启内核