Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 装饰器如何标记函数?_Python_Flask_Decorator_Python Decorators - Fatal编程技术网

Python 装饰器如何标记函数?

Python 装饰器如何标记函数?,python,flask,decorator,python-decorators,Python,Flask,Decorator,Python Decorators,我正在阅读基本烧瓶教程,其中包含以下代码: from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run() 我还学习了许多网站上Python装饰器的基础知识,包括 我假设在前面的代码中,函数hello将被更改和修饰,为了运行应用程序,我需要在某处调用函数hello()。Fl

我正在阅读基本烧瓶教程,其中包含以下代码:

from flask import Flask
app = Flask(__name__)

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

if __name__ == "__main__":
    app.run()
我还学习了许多网站上Python装饰器的基础知识,包括

我假设在前面的代码中,函数
hello
将被更改和修饰,为了运行应用程序,我需要在某处调用函数
hello()
。Flask如何确定它必须调用的函数的名称

仅仅用修饰符包装函数定义是否会以某种方式标记该函数?如果是,怎么做

例如,在下面的代码中,我调用了我修饰过的函数:

def decorate(foo):
    print("I'm doing a lot of important stuff right now")

    def inner():
        print("Some stuff 1")
        foo()
        print("Some stuff 2")

    return inner

@decorate
def hello():
    print("Hello")

hello()

decoration
中,
foo
是您要修饰的函数(在本例中,
hello
)。您可以将函数存储在列表或字典中的某个位置,因为它是一个普通对象

例如:

decorated_functions = []

def decorate(foo):
    def inner():
        print("Some stuff 1")
        foo()
        print("Some stuff 2")

    decorated_functions.append(inner)
    return inner

@decorate
def hello():
    print("Hello")

## The above is the same as:
# def hello():
#     print("Hello")
# hello = decorate(hello)

print(decorated_functions[0] == hello) # prints True
decorated_functions[0]() # prints "Some stuff 1", "Hello", and "Some stuff 2"
hello() # same as above

decoration
中,
foo
是您要修饰的函数(在本例中,
hello
)。您可以将函数存储在列表或字典中的某个位置,因为它是一个普通对象

例如:

decorated_functions = []

def decorate(foo):
    def inner():
        print("Some stuff 1")
        foo()
        print("Some stuff 2")

    decorated_functions.append(inner)
    return inner

@decorate
def hello():
    print("Hello")

## The above is the same as:
# def hello():
#     print("Hello")
# hello = decorate(hello)

print(decorated_functions[0] == hello) # prints True
decorated_functions[0]() # prints "Some stuff 1", "Hello", and "Some stuff 2"
hello() # same as above

装饰器实际上是Python中一个非常简单的构造。以下两个示例是等效的:

@foo
def bar():
     pass

因此,您在第一个示例中对
hello
的定义与此等效:

def hello():
     return "Hello World!"

hello = app.route("/")(hello)
双函数调用可能有点混乱,因此让我们像这样重写它:

_tempfn = app.route("/")
hello = _tempfn(hello)
class app(object):
    def route(self, path):
        def decorator(fn):
            self.pathmap[path] = fn
            return fn
        return decorator
所以现在应该很清楚,
app.route
实际上不是一个装饰器,而是一个创建装饰器的函数。现在不明显的是新来的装饰师做了什么。如果不查看Flash的源代码,它很可能会将函数
hello
添加到
应用程序的字典成员中。因此,
app.route
实现如下:

_tempfn = app.route("/")
hello = _tempfn(hello)
class app(object):
    def route(self, path):
        def decorator(fn):
            self.pathmap[path] = fn
            return fn
        return decorator

请注意,这是链接中给出的解释的浓缩版本。

装饰符实际上是Python中非常简单的构造。以下两个示例是等效的:

@foo
def bar():
     pass

因此,您在第一个示例中对
hello
的定义与此等效:

def hello():
     return "Hello World!"

hello = app.route("/")(hello)
双函数调用可能有点混乱,因此让我们像这样重写它:

_tempfn = app.route("/")
hello = _tempfn(hello)
class app(object):
    def route(self, path):
        def decorator(fn):
            self.pathmap[path] = fn
            return fn
        return decorator
所以现在应该很清楚,
app.route
实际上不是一个装饰器,而是一个创建装饰器的函数。现在不明显的是新来的装饰师做了什么。如果不查看Flash的源代码,它很可能会将函数
hello
添加到
应用程序的字典成员中。因此,
app.route
实现如下:

_tempfn = app.route("/")
hello = _tempfn(hello)
class app(object):
    def route(self, path):
        def decorator(fn):
            self.pathmap[path] = fn
            return fn
        return decorator

请注意,这几乎是链接中给出的解释的浓缩版本。

装饰程序只是在查找表中注册函数。decorator不需要以任何方式修改函数,decorator可以做很多其他有用的事情

事实上,python中的装饰程序

@some_decorator
def foo():
    pass
只是一个简短的形式

def foo():
    pass

foo = some_decorator(foo)

函数
some_decorator
可以对其参数执行任何操作,可以返回任何返回值,但通常返回函数。

decorator只是在查找表中注册函数。decorator不需要以任何方式修改函数,decorator可以做很多其他有用的事情

事实上,python中的装饰程序

@some_decorator
def foo():
    pass
只是一个简短的形式

def foo():
    pass

foo = some_decorator(foo)

函数
some_decorator
可以对其参数执行任何操作,可以返回任何返回值,但通常会返回一个函数。

此链接可能会有所帮助:如果您了解了基础知识,那么您应该知道我们仍然可以使用名称
hello
访问它,因为上面的内容相当于:
hello=@app.route(“/”(hello)
。但要实现这一点,我需要调用
hello()
,这不是我在Flask中做的code@KartikAnand您不必这样做,因为当访问路由
'/'
时,flask会为您这样做。类似地,在第二个示例中,当您调用
hello()
时,您实际上正在调用
internal()
调用实际的
hello()
@AshwiniChaudhary我理解调用
hello()
调用
internal()
,然后调用原始的
hello()
。我不理解的是Flask如何访问原始的
hello())
/
内部。此链接可能会有所帮助:如果您学习了基本知识,那么您应该知道我们仍然可以使用名称
hello
访问它,因为上面的内容相当于:
hello=@app.route(“/”)(hello)
。但是要实现此目的,我需要调用
hello()
,这不是我在烧瓶里做的code@KartikAnand您不必这样做,因为当访问路由
'/'
时,flask会为您这样做。类似地,在第二个示例中,当您调用
hello()
时,您实际上调用的是
internal()
,后者反过来调用实际的
hello()
@AshwiniChaudhary我理解调用
hello()
调用
internal()
并反过来调用原始
hello()
。我不理解的是Flask如何访问原始
hello())
内部
/
代码中的
打印
语句是如何工作的?我没有调用任何函数,那么列表是如何填充的?@kartikan您已经调用了
装饰
函数;请参见编辑。因此,当我装饰一个函数时,它会调用它,因此我可以将它保存在列表中。
打印
语句是如何工作的你的代码工作中有什么内容?我没有调用任何函数,那么列表是如何填充的?@kartikan你已经调用了
修饰
函数;请参见编辑。因此,我修饰一个函数的那一刻,它就会调用它,这样我就可以将它保存在列表中了!