【python】函数、闭包以及装饰器

本文详细解释了函数、闭包和装饰器在Python中的概念及其区别,指出装饰器如何利用闭包修改函数行为,以及在Flask框架中route装饰器的实际应用。
摘要由CSDN通过智能技术生成

一、函数和闭包的区别

函数:函数是一段可重复使用的代码,它可以接受输入参数并返回结果。函数在定义时不会记住任何数据或状态。

闭包:闭包是一种特殊的函数,它记住了其外部函数的局部变量值。这意味着即使外部函数已经返回,闭包仍然可以访问和修改这些变量。

可以举一个形象的例子:函数和闭包就像是紫菜包饭和寿司,一个馅是在里面,而另一个在外面。

def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

add_five = outer_function(5)
print(add_five(10))  # 输出:15

这里就是一个闭包的例子,我们定义了一个函数叫outer,在outer里定义了一个内部函数inner。而里面的inner可以使用外部函数outer的x变量,这样可以防止全局变量的滥用,而最外层的add_five则是一个闭包。你可以理解成,add_five是outer函数的一个‘实例’,经过add_five = outer_function(5)之后,这个add_five就变成了一个函数(期待输入inner的y参数)。

装饰器

而装饰器的作用也有相似之处:装饰器本质上是一个接收函数作为参数并返回一个新函数的函数。
这里的@my_decorator是一种简单的表示装饰器的方法 。

def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

当我们调用say_hello() 时,Python会自动将 say_hello 函数作为参数传递给 my_decorator 函数,然后用 my_decorator 函数的返回值(即 wrapper 函数)替换 say_hello 函数。实际上我们调用的是 wrapper 函数。因此,输出会是:

Before function call
Hello!
After function call

因此,我们可以说 my_decorator 装饰了 say_hello 函数。在这个过程中,say_hello 函数的行为被修改了:当我们调用 say_hello() 时,实际上我们调用的是 wrapper 函数,它在调用原始的 say_hello 函数之前和之后打印了一些消息。

闭包和装饰器

首先,装饰器和闭包都是高阶函数,即它们都是接收函数作为参数或返回函数的函数。

然而,它们用于解决的问题是不同的:装饰器用于修改函数或类的行为,而闭包用于记住函数的状态。也可以说,装饰器更进一步,它使用这些概念来修改或增强其他函数的行为。

同时我们可以发现,装饰器往往用到了闭包,这是因为装饰器要实现给函数添加行为这个功能,需要接受函数做参数,也需要返回新函数:

(1)装饰器通过接收一个函数作为参数,可以对这个函数进行包装或修改。

(2)装饰器通过返回一个新的函数,可以改变原函数的行为。这个新函数通常会调用原函数,并在调用前后添加一些额外的逻辑。

这两个特性使得装饰器需要使用闭包。

flask中的route

在使用flask框架时,总能发现一个叫route的装饰器,它的主要作用是将函数绑定到一个URL,当flask处理请求的时候,会检查其请求的URL,然后调用与这个URL关联的函数。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, World!"

if __name__ == '__main__':
    app.run()

在这个例子中,@app.route('/') 装饰器将 home 函数绑定到了 URL '/'。当你访问 http://localhost:5000/(默认的地址和端口)时,Flask 会调用home函数,并将其返回值作为 HTTP 响应发送给客户端。route() 装饰器内部的实现可能会比这个例子复杂得多,因为它需要处理各种各样的情况,如不同的 HTTP 方法(GET、POST 等)、动态路由、URL 转换等。但是,从最基本的层面来看,route() 装饰器就是一个使用了闭包的装饰器,它将 URL 路径映射到视图函数。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值