" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper博主等级

千里之行,始于足下

  • 累计撰写 203 篇文章
  • 累计创建 14 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Python 闭包 装饰器

PySuper
2024-06-19 / 0 评论 / 0 点赞 / 53 阅读 / 6422 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

使用 () 调用函数时,主要发生的事情包括查找函数对象、创建调用帧(包含了函数的局部变量和执行环境等信息)、参数传递、执行函数体和返回值(如果函数没有显式地返回值,它会隐式地返回 None

这一过程使得我们能够动态调用和执行函数

  • 函数式编程

  • 代码重用

闭包

基本概念

闭包(Closure)是指一个函数内部定义的函数,并且这个内部函数能够引用外部函数中的变量,即使外部函数已经执行完毕。

特点:

  • 嵌套函数:闭包必须有一个内部函数

  • 自由变量:内部函数使用外部函数的变量

  • 返回内部函数外部函数返回内部函数的引用

inner_function就是一个闭包,因为它引用了外部函数outer_function的变量message

正常来说,调用一个函数的时候,这个函数中的所有局部变量和形参,都只会在这个函数执行的过程中才会保留,只要这个函数执行完毕,这些局部变量和形参就会被自动释放,也就是没有了。

闭包比普通函数强大的地方在于,它在外部函数执行完毕之后,这个外部函数中的所有局部变量和形参,都不会被释放,而是等到内部函数执行完毕,以便于调用内部函数的时候可以使用。

  • 好处:可以将局部变量永久存储

  • 坏处:占用内存

    • 普通函数:[A() for i in range]循环一次 释放一次,100次也只有一次的A()数据

    • 闭包函数:[B() for i in range]数据一直保存在内存中,每次循环都会创建新的 保存下来

def outer_function(msg):
    message = msg

    def inner_function():
        print(message)

    return inner_function


closure = outer_function("Hello, World!")

closure()

nonlocal

在嵌套函数中修改外部非全局变量。它告诉Python解释器,在当前作用域内寻找该变量,而不是在局部作用域内定义一个新变量

def outer_function():
    count = 0

    def inner_function():
		# 表示 count 不是局部变量,而是外部函数 outer_function 中的变量
		# 每次调用 inner_function 时,它都会修改 outer_function 中的 count 变量
        nonlocal count
        count += 1
        print(count)

    return inner_function

closure = outer_function()

closure()  # 输出: 1
closure()  # 输出: 2
closure()  # 输出: 3

多个内部函数

一般还是只写一个内部函数

def counter_operations(initial_count):
    count = initial_count

    def increment():
        nonlocal count
        count += 1
        return count

    def decrement():
        nonlocal count
        count -= 1
        return count

    return increment, decrement

# 创建闭包
increment_func, decrement_func = counter_operations(10)

# 使用闭包
print(increment_func())  # 输出: 11
print(increment_func())  # 输出: 12
print(decrement_func())  # 输出: 11
print(decrement_func())  # 输出: 10

外部函数变量

  • 闭包中,外部函数的变量,不会被立即销毁(便于内部函数调用)

  • 可以重复使用外部函数变量,或者是不断覆盖,不断使用 赋值 之后的外部函数变量

def create():

    # 定义坐标原点
    pos = [0, 0]

    def player(direction, step):
        # 这里的pos是全局变量, new_x,new_y是局部变量,局部变量会覆盖全局变量
        new_x = pos[0] + step * direction[0]
        new_y = pos[1] + step * direction[1]

        # 外部函数中的变量,不会立即销毁,这里用new_x/new_y覆盖了 外部函数的变量
        # 下一次进入函数的时候,使用的就是 外部函数中的变量,值 却是上一次修改的值
        pos[0] = new_x
        pos[1] = new_y
        return pos

    return player


player = create() # 返回的是 player 函数

print(player([1, 0], 10))
print(player([0, 1], 20))
print(player([-1, 0], 20))

装饰器

装饰器(Decorator)是一种高级函数,用于在不改变函数本身的情况下,扩展或修改其功能

装饰器本质上是一个返回函数的函数

装饰器通过使用@decorator_name语法来应用

示例:

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        print(f"Wrapper executed this before {original_function.__name__}")
        return original_function(*args, **kwargs)

    return wrapper_function


@decorator_function
def display():
    print("Display function ran")


display()

@decorator_function是装饰器,它会修改display函数的行为,使其在执行原始函数之前打印一条信息

两者比较

装饰器通常利用闭包来实现

装饰器的内部函数(wrapper function)引用了装饰器外部函数的变量(如原始函数),从而形成闭包

  • 闭包:用于保存函数的环境,使得内部函数可以记住和访问外部函数的变量

  • 装饰器:用于动态地修改或扩展函数的行为,通常通过闭包实现

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区