最详细爬虫零基础教程07——闭包以及装饰器


前言

本文主要介绍的是一个额外的内容,方便后面学习所用到的知识。


一、闭包

闭包(Closure)是一种函数的组合,它包含了一个函数和与其相关的引用环境。换句话说,闭包是指在一个函数内部定义的函数,它可以访问外部函数的变量,并将其保存在函数内部。

在Python中,通过使用嵌套函数和return语句,可以创建闭包。具体来说,当一个内部函数引用了外部函数的变量时,闭包就形成了。

简单来说,闭包的三个条件就是:

  1. 两个函数嵌套
  2. 内部函数使用到了外部函数的变量
  3. 外部函数返回值是内部函数名
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

closure = outer_function(10)
print(closure(5))  # 输出15

在上面的例子中,outer_function是外部函数,inner_function是内部函数。inner_function引用了外部函数的变量x,形成了闭包。我们通过调用outer_function(10)返回了闭包函数inner_function,并将其赋给变量closure。然后我们可以通过调用closure(5)来使用闭包。

闭包的特点是可以将外部函数的局部变量保留在内存中,即使外部函数已经执行结束,闭包仍然可以访问这些变量。这使得闭包具有一定的灵活性和功能性,可以用来实现一些特殊的逻辑和业务需求。需要注意的是,闭包可以修改外部函数的变量,但是这种修改是持久的,会影响后续对闭包的调用。因此,在使用闭包时需要谨慎处理变量的修改。

二、装饰器

  1. 单个装饰器

装饰器(Decorator)是Python中一种特殊的函数,用于修改其他函数的功能。它可以在不改变原函数代码的情况下,为函数添加额外的功能,例如日志记录、性能测试、权限验证等。

装饰器的语法是使用@符号将装饰器函数应用到被修饰函数上。

代码如下(示例):

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        # 在调用被修饰的函数之前添加额外的功能
        print("装饰器函数被调用")
        # 调用被修饰的函数
        result = original_function(*args, **kwargs)
        # 在调用被修饰的函数之后添加额外的功能
        print("装饰器函数调用结束")
        return result
    return wrapper_function

@decorator_function  # 相当de = decorator_function(target_function)
def target_function():
    print("目标函数被调用")

target_function()  # de()

装饰器的使用可以灵活地根据需求来增强函数的功能,且不需要修改原函数的代码。它是 Python 中一种强大的编程技巧。常见的应用场景包括日志记录、性能测试、权限验证、缓存等。

  1. 多个装饰器

调用顺序:遵循就近原则

def outer(fn):
    def inner():
        return '哈' + fn() + '哈'
    return inner

def outer2(fn):
    def inner():
        return '嘿' + fn() + '嘿'
    return inner

@outer
def s1():
    return 'hello'

@outer2
def s2():
    return 'python'

print(s1())  # 哈hello哈
print(s2())  # 嘿python嘿

@outer
@outer2
def s3():
    return 'world'

print(s3())  # 哈嘿world嘿哈
  1. 类装饰器
class check:
    def __init__(self, fn):  # 因此要用一个init方法,增加一个参数用于接受被修饰的函数
        self.__fn = fn

    # 实现call方法,表示对象是一个可调用对象,可以像函数一样调用
    def __call__(self, *args, **kwargs):
        # 添加装饰功能
        print('请先登录...')
        self.__fn()  # self.fn 等价于fn  fn又等于comment


@check   # 等价于comment = check(comment)

def comment():
    print('发表评论')

comment()

总结

本节内容有一点难理解,建议多花一点时间来进行学习。

只有极致的拼搏,才能配得上极致的风景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莘薪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值