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至关重要。这也是内部函数的主要使用场景。
相关推荐
喵叔哟1 小时前
Week 3 --Day 5:性能优化与监控
人工智能·python·性能优化·langchain
多彩电脑1 小时前
SwiftUI的导航界面的嵌套问题
开发语言·swift·设计语言
.千余1 小时前
【C++】C++ map 与 multimap 完全指南:键值对容器详解
开发语言·c++·笔记·学习·其他
牢姐与蒯1 小时前
c++数据结构之c++11(三)
开发语言·c++
暗黑小白1 小时前
第八篇:人在回路与内容安全 —— 当 AI 说“让我请示一下“
python·安全·架构·ai agent
hoiii1871 小时前
17自由度铁道车辆横向动力学MATLAB程序
开发语言·matlab
大蚂蚁2号1 小时前
Python 项目架构深度解析:从混乱到清晰
开发语言·python·架构
老徐聊GEO2 小时前
AI搜索流量转化率实测分享:我的案例与复盘
人工智能·python
草莓熊Lotso2 小时前
【LangChain】流式传输原理与 LangSmith 应用监控全解析
人工智能·python·langchain·gpt-3