编辑 2:我误解了装饰器的工作方式。即使未调用装饰函数,装饰器也会运行(即使您可能看不到它的效果)。 function = dec(function) 将是显示装饰器功能的等效方式,显然在这种情况下 dec() 函数在没有任何调用 function() 的情况下运行。
编辑:为什么我的帖子在没有解释的情况下被否决?我该如何解决?有多种答案,其中一个清楚地回答了问题。问题是什么?
我一直在学习 Python 中的装饰器,我认为我对它们有很好的掌握。但是,我仍然对 app.route 装饰器在 flask 中的工作方式感到有些困惑。根据我的理解,装饰器会更改函数的行为,但除非调用该函数,否则不会运行。所以如果我有:
@app.route("/")
def hello():
return "Hello world"
hello()
hello 函数将被传递给 app.route 并且装饰器指示的任何行为都将执行。然而,在flask应用程序中,函数本身似乎从未运行过(在我上面的例子中是这样)。如果路由函数/装饰器从未调用过它所装饰的函数,它是如何执行的?我知道 app.route 本质上将“/”及其相应的函数存储在字典中,但我不明白在没有任何装饰函数调用的情况下如何执行此代码。我假设它以某种方式连接到 flask 应用程序末尾的 app.run 但我不清楚 app.run 如何调用您定义的函数。
编辑:添加到我在这里展示的内容。这个解释有一个例子:https://ains.co/blog/things-which-arent-magic-flask-part-1.html这提出了同样的问题。我认为需要调用 hello() 以便路由函数执行任何操作。
class NotFlask():
def __init__(self):
self.routes = {}
def route(self, route_str):
def decorator(f):
self.routes[route_str] = f
return f
return decorator
def serve(self, path):
view_function = self.routes.get(path)
if view_function:
return view_function()
else:
raise ValueError('Route "{}"" has not been
registered'.format(path))
app = NotFlask()
@app.route("/")
def hello():
return "Hello World!"
最佳答案
像这样的 Python 装饰器:
@decorator
def func():
pass
可以改为如下所示:
def func():
pass
decorator(func)
或者换句话说,它们是带函数的函数。在某些情况下,您可能不会立即看到装饰器的效果,因此在调用它装饰的函数之前,装饰器本身似乎不会被使用,但这并不是 Python 装饰器的实际限制。
在您的代码中,
@app.route("/")
是一个装饰器,它将端点添加到 app
目的。它实际上并没有修改函数的任何行为,而是简化过程的糖。没有 route()
装饰器,这就是您在 Flask 中进行等效路由注册的方式。from flask import Flask
app = Flask(_name_)
def hello():
return "Hello world"
app.add_url_rule("/", "hello", hello)
如果你看看 implementation of the
route
decorator在 Flask 中,你会看到这是等价的。def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage::
@app.route('/')
def index():
return 'Hello World'
For more information refer to :ref:`url-route-registrations`.
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (``GET``, ``POST`` etc.). By default a rule
just listens for ``GET`` (and implicitly ``HEAD``).
Starting with Flask 0.6, ``OPTIONS`` is implicitly
added and handled by the standard request handling.
"""
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
所以你可以看到
route
将它添加到应用程序的路由器,因此一旦 Flask 应用程序收到请求,它就会决定如何为所请求的端点执行代码/ View 。
关于python - 装饰函数如何在 flask /python 中工作? (app.route),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46123448/