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至关重要。这也是内部函数的主要使用场景。
相关推荐
yoothey37 分钟前
报废审批流规则引擎设计——责任链模式完整实现
linux·开发语言·bash
geovindu1 小时前
python: Functional Options Pattern
开发语言·后端·python·设计模式·惯用法模式·函数式选项模式
wuyk5551 小时前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机
tryCbest1 小时前
Python 文件操作
服务器·python
凯瑟琳.奥古斯特2 小时前
K次取反最大化数组和解法(力扣1005)
开发语言·c++·算法·leetcode·职场和发展
涛声依旧-底层原理研究所2 小时前
Agent 长任务可靠性设计:实现暂停、恢复、续跑与崩溃重启的完整方案
人工智能·python·系统架构
AC赳赳老秦2 小时前
防火墙规则批量配置实战:OpenClaw 自动生成模板、批量下发与合规性校验全解析
java·开发语言·人工智能·python·github·php·openclaw
小小编程路2 小时前
如何优化while循环的性能?
python
☆cwlulu2 小时前
调试排查工具介绍(gdb、strace、Valgrind等)
开发语言·c++·嵌入式硬件·ubuntu
C语言小火车3 小时前
C++ 快速排序(Quick Sort)深度精讲:分治思想、Lomuto 分区法及三数取中优化,面试手撕必会
c语言·开发语言·c++·面试·排序算法·快速排序