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至关重要。这也是内部函数的主要使用场景。
相关推荐
jufeng13071 小时前
【系列:手搓自主 AI Agent:Hermes 架构原理剖析 · 第 8 篇】
python·ai agent·配置系统
circuitsosk1 小时前
跨境电商智能化实战:AI如何赋能客服自动回复、广告智能投放与供应链预测
大数据·人工智能·python·langchain·智能客服
2601_956319882 小时前
2026年零基础学量化:从看懂示例到写清条件和动作
人工智能·python
知无不研2 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
过期的秋刀鱼!3 小时前
LangChain-D1-模型的工作流程
人工智能·python·langchain
萤火工厂目视化设计3 小时前
智能制造与企业文化目视化浪潮下:中小工厂的机遇与挑战
python·制造
cfm_29143 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
DeepVisionary4 小时前
从GPT-5.6 Sol的Ultrafast模式看推理速度竞赛:750 token/秒背后,Cerebras的晶圆级生意
python·自动化
C++ 老炮儿的技术栈4 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011164 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组