python3装饰器

概念

装饰器本质:接收函数作为参数,返回新函数 ,在不修改原函数代码、不改变原函数调用方式 的前提下,给函数新增功能(日志、计时、权限、缓存、重试等)。

它允许你修改函数或类的行为,而不更改其源代码。实质上,装饰器是接受另一个函数作为参数并返回一个包装原始函数的新函数。这样,你可以在不修改原始函数的情况下,添加一些额外的功能或逻辑。

复制代码
def time_cost(func):
    """
    :return:
    """

    def wrapper(*args, **kwargs):
        """
        :param args:
        :param kwargs:
        :return:
        """
        start = int(time.time() * 1000)
        func(*args, **kwargs)
        end = int(time.time() * 1000)
        print("call api time cost:%s ms" %
                 (end - start))

    return wrapper
python 复制代码
def ntimes(n):

    def inner(f):

        def wrapper(*args, **kwargs):
            for _ in range(n):

                rv = f(*args, **kwargs)
            return rv

    return wrapper
return inner



#然后你可以使用上述函数包装另一个函数,例如前文中的 add 函数:
@ntimes(3)
def add(x, y):
    print(x + y)
return x + y

最简单装饰器(无参装饰器)

写法 1:原生嵌套函数(理解原理)

复制代码
# 定义装饰器
def decorator(func):
    # 内层包装函数
    def wrapper():
        print("执行前:新增逻辑")
        func()  # 调用原函数
        print("执行后:新增逻辑")
    return wrapper

# 普通函数
def say_hello():
    print("Hello World")

# 手动装饰
say_hello = decorator(say_hello)
# 调用(调用的是 wrapper)
say_hello()

写法 2:语法糖 @(工程常用)

不用手动赋值,@装饰器名 放在函数上方 ,等价于 func = decorator(func)

复制代码
def decorator(func):
    def wrapper():
        print("前置逻辑")
        func()
        print("后置逻辑")
    return wrapper

# 语法糖装饰
@decorator
def say_hello():
    print("Hello World")

say_hello()

Python中有许多内置的装饰器

例如@staticmethod、@classmethod、@property、@functools.lru_cache、@functools.singledispatch等。你还可以为不同的目的创建自己的自定义装饰器。

闭包函数

闭包函数就是定义在函数内部的函数,也就是函数的嵌套定义,根据字面意思理解,闭包函数有两个关键字闭和包分别是的封闭和包裹。需要注意的重点是:闭包函数的作用域关系在函数定义阶段就固定死了,与调用位置无关。

1.什么是闭包函数:一个函数的返回值是另外一个函数,返回的函数调用父函数内部的变量,如果返回的函数在外部被执行,就产生了闭包

2.闭包函数的作用:使函数外部能够调用函数内部放入属性和方法

3.闭包函数的优缺点:

优点:使函数外部能够调用函数内部放入属性和方法

缺点:闭包操作导致整个函数的内部环境被长久保存,占用大量内存

__closure__属性。Python给内部函数添加了这个属性来携带内部函数用到的外部函数中的变量。

闭包作用

数据隐藏

闭包可以创建私有变量,避免全局污染。外部无法直接访问闭包内部的变量,只能通过闭包暴露的方法操作。

javascript 复制代码
const module = (function() {
  let privateVar = 0;
  function privateMethod() {
    return privateVar;
  }
  return {
    publicMethod: function() {
      return privateMethod();
    }
  };
})();
console.log(module.publicMethod()); // 输出 0
 

DRY 原则

模块化开发

闭包是实现模块化的重要方式,通过返回对象或函数暴露接口,隐藏内部实现细节。

延长变量生命周期

外部函数的变量在执行后通常会被销毁,但闭包会保留对这些变量的引用,使其存活时间更长。

javascript 复制代码
function delayLog(msg, time) {
  setTimeout(function() {
    console.log(msg); // 闭包保留了msg的引用
  }, time);
}
delayLog("Hello", 1000); // 1秒后输出 "Hello"
 

函数柯里化

闭包可以用于柯里化(Currying),将多参数函数转换为单参数链式调用。

javascript 复制代码
function add(x) {
  return function(y) {
    return x + y;
  };
}
const add5 = add(5);
console.log(add5(3)); // 输出 8
 

闭包函数使用场景

  1. 封装:这种场景叫做封装
  2. 内部函数可以方便的生成新的函数
  3. 装饰器:对Python至关重要。这也是内部函数的主要使用场景。
相关推荐
EasyGBS2 分钟前
从接入到稳定播放:无插件直播H5视频流媒体播放器EasyPlayer.js如何撑起Web端流媒体
开发语言·前端·javascript
FfHUCisI4 分钟前
GMP 调度器:Go 并发的心脏是如何跳动的
开发语言·golang·php
Carl_奕然8 分钟前
【智能体】Agent的四种设计模式之:React(2026最新版)
javascript·人工智能·python·react.js·设计模式·语言模型
岁月宁静10 分钟前
四、《从零手撸 Agent》 — 流式输出:接住 AI “一个字一个字” 想出来的过程
python·agent
Java小白笔记11 分钟前
Java 实现阿里云 OSS 文件上传链路:普通上传、秒传、分片与断点续传
java·开发语言·数据库·spring·阿里云
传奇开心果编程13 分钟前
【Rust入门知识点学与练】第9课:Vec 动态数组
开发语言·学习·rust
是吕先森13 分钟前
【python】selenium实现web自动化测试
前端·python·selenium
卢锡荣16 分钟前
单芯掌控多口互联|乐得瑞 LDR6020 PD3.1 多通道 Type‑C 控制 SOC 芯片
c语言·开发语言
2333!!!!!16 分钟前
rocket新手一些常见问题
java·开发语言
yume_sibai18 分钟前
02-Rust 所有权与借用深入解析(底层原理 + 借用检查器 + 生命周期 + 内部可变性)
开发语言·后端·rust