装饰函数如何在flask / python中工作? (应用路线) [英] how do decorated functions work in flask/python? (app.route)

查看:76
本文介绍了装饰函数如何在flask / python中工作? (应用路线)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑2:我误解了装饰器的工作方式。即使未调用装饰函数,装饰器也会运行(即使您可能看不到它的效果)。 function = dec(function)是显示装饰器功能的等效方法,显然,在这种情况下dec()函数运行时无需调用function()。

Edit 2: I misunderstood how decorators work. The decorator is run even if the decorated function is not called (even though you might not see it's effects). function = dec(function) would be an equivalent way of showing what a decorator does and obviously in that scenario the dec() function runs without any calls to function().

编辑:为什么我的帖子没有说明就被否决?我该如何解决?有多个答案,一个可以明确回答问题。问题是什么?

Why is my post being down voted with no explanation? How can I fix it? There are multiple answers, one which clearly answers the question. What is the issue?

我一直在学习python中的装饰器,我认为我对它们有很好的了解。但是,我仍然对烧瓶中的app.route装饰器如何工作感到有些困惑。据我了解,装饰器会更改函数的行为,但除非调用该函数,否则它不会运行。因此,如果我有:

I've been learning about decorators in python and I think I have a good grasp on them. However I am still slightly confused about how the app.route decorator works in flask. By my understanding the decorator changes the behavior of a function but does not run unless the function is called. So if I have:

@app.route("/")
def hello():
    return "Hello world"

hello()

hello函数将传递给app.route,装饰器指示的任何行为都将执行。但是,在flask应用程序中,该函数本身似乎从未运行过(在我上面的示例中是)。如果路由功能/装饰器的功能从未调用过,如何执行?我知道app.route本质上将 /及其对应的函数存储在字典中,但是我不理解在没有任何修饰函数调用的情况下如何执行此代码。我假设它在烧瓶应用程序的末尾以某种方式连接到app.run,但是我不清楚app.run如何调用您定义的函数。

The hello function will get passed to app.route and whatever behavior the decorator dictates will execute. However in flask apps the function itself never appears to be run (in my above example it is). How is the route function/decorator executed if the function it decorates is never called? I know that app.route essentially stores the "/" along with its corresponding function in a dictionary but I don't understand how this code is ever executed without any calls of the decorated function. I assume it is somehow connected to the app.run at the end of flask apps but I am unclear on how app.run can call the functions you defined.

编辑:添加到我在这里显示的内容。此说明中有一个示例: https:// ains .co / blog / things-which-arent-magic-flask-part-1.html 提出了同样的问题。我认为需要调用hello()才能使route函数执行任何操作。

to add to what I've shown here. There is an example from this explanation: https://ains.co/blog/things-which-arent-magic-flask-part-1.html That raises the same questions. I would think that hello() needs to be called in order for the route function to do anything.

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装饰器:

Python decorators like this:

@decorator
def func():
    pass

可以改为如下所示:

def func():
    pass

decorator(func)

换句话说,它们是带有函数的函数。在某些情况下,您可能不会立即看到装饰器的效果,因此看起来装饰器本身直到被调用的装饰器函数才被使用,但这并不是Python装饰器的实际限制。

Or in other words, they're functions that take functions. In some circumstances, you might not see the effects of the decorator immediately, so it may seem like the decorator itself isn't used until the function it decorates is called, but that's not an actual restriction of Python decorators.

在您的代码中, @ app.route( /)是一个装饰器,它将终结点添加到 app 对象。它实际上并没有修改函数的任何行为,而是简化过程的糖。没有 route()装饰器,这就是在Flask中进行等效路由注册的方式。

In your code, @app.route("/") is a decorator which adds an endpoint to the app object. It doesn't actually modify any behavior of the function, and is instead sugar to simplify the process. Without the route() decorator, this is how you'd do the equivalent route registration in Flask.

from flask import Flask
app = Flask(_name_)

def hello():
    return "Hello world"

app.add_url_rule("/", "hello", hello)

路线装饰器在Flask中,您会看到它是等效的。

And if you look at the implementation of the route decorator in Flask, you'll see that this is the equivalent.

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应用获得请求,它便决定如何为请求的端点执行代码/视图。

So you can see that route adds it to the app's router, so once the Flask app gets a request, it decides how to execute code/view for the endpoint that's been requested.

这篇关于装饰函数如何在flask / python中工作? (应用路线)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆