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你已经调用了修饰函数;请参见编辑。因此,我修饰一个函数的那一刻,它就会调用它,这样我就可以将它保存在列表中了!