首页 > 编程语言 >python闭包

python闭包

时间:2023-09-17 23:55:57浏览次数:51  
标签:闭包 closure return 函数 python result func

python中的闭包

1、什么是闭包

2、闭包的作用域问题

3、闭包的应用场景


1、什么是闭包

闭包指的是闭包函数,与函数嵌套的区别在于闭包函数(内层函数)会使用到外层函数的变量。

  • 构成闭包的几个条件

1、一个函数必须有一个内层函数;

2、内层函数必须使用到外层函数的变量;

3、外层函数必须返回内层函数。

例如:

def outer_func(x):
    a = 1
    b = 2
    def inner_func(y):
        return x + y + a + b
    return inner_func

closure_func = outer_func(10) #给外部函数传入参数10
print(closure_func.__closure__)  # 输出 (<cell at 0x7f856b37e9c0: int object at 0x7f856b37e9c0>,)
cell0 = closure_func.__closure__[0] 
cell2 = closure_func.__closure__[1] 
cell3 = closure_func.__closure__[2] 
print(cell0.cell_contents,cell2.cell_contents,cell3.cell_contents) #输出1,2,10

print(closure_func(5)) #给内层函数传入参数5

2、闭包的作用域问题

在分析python函数闭包的作用域问题前首先要知道python中函数对象的一个属性:_closure_

  • 在 Python 中,closure 是一个内置属性,用于访问一个闭包(closure)的外部变量(自由变量)。

从上面的例子中可以看到在outer_func函数被调用完后,通过访问__closure__属性得到了一个元组这个元组中存放的就是闭包的内层函数使用到的外层函数的变量,后面通过cell_contents方法访问元组中的每个元素分别得到了1,2,10,这三个值正好是外层函数的a,b,x变量。

  • 可以理解成在使用闭包函数时,python会自动将内层函数所使用到的外层函数的变量放入调用闭包函数的对象的__closure__属性对应的元组中如上面例子的closure.func._closure_

3、闭包的应用场景

  • 1、装饰器
def logger(func):
    def wrapper(*args, **kwargs):
        print("调用函数: ", func.__name__)
        return func(*args, **kwargs)
    return wrapper

@logger
def add(x, y):
    return x + y

result = add(2, 3)  # 输出:调用函数: add
print(result)  # 输出:5
  • 2、延迟执行
def lazy_evaluation():
    result = None

    def calculate():
        nonlocal result
        if result is None:
            result = 10 + 20  # 这里可以是复杂的计算过程
        return result

    return calculate

lazy_calculation = lazy_evaluation()

# ...

result = lazy_calculation()  # 真正执行计算,返回结果
print(result)  # 输出:30
  • 3、计数器
def counter():
    count = 0

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

    return increment

counter1 = counter()
print(counter1())  # 输出:1
print(counter1())  # 输出:2

counter2 = counter()
print(counter2())  # 输出:1
  • 4、缓存
def cache():
    cached_results = {}

    def calculate_or_get_cached_result(x):
        if x in cached_results:
            return cached_results[x]
        else:
            result = x * 2  # 这里可以是复杂的计算过程
            cached_results[x] = result
            return result

    return calculate_or_get_cached_result

calculate = cache()

# ...

result1 = calculate(5)  # 第一次计算,结果将被缓存
print(result1)  # 输出:10

result2 = calculate(5)  # 直接从缓存中获取结果
print(result2)  # 输出:10

标签:闭包,closure,return,函数,python,result,func
From: https://www.cnblogs.com/littlejazzcat/p/17710296.html

相关文章

  • python值传递与引用问题
    关于python中的值传递与引用问题首先看下面这段代码'''original_list=[1,2,[3,4]]copied_list=original_listcopied_list[2][0]='a'print(original_list)输出结果为[1,2,['a',4]]这里本意是想为original_list复制一个副本后使用从而不更改原始列表的值,但是......
  • python多线程
    Python多线程参考文章:python多线程详解(超详细)、Python线程池(threadpool)创建及使用+实例代码、第二十章多线程1、多线程的概念2、python多线程的基本使用方法3、多线程的优点及与多进程的关系1、多线程的概念线程也叫轻量级进程,是操作系统能够进行运算调度......
  • Python入门系列1-基础语法
    一、标识符标识符由字母、数字和下划线组成,但是不能以数字开头。标识符是区分大小写的。以下划线开头的标识有特殊意义。以单下划线开头_foo的代表不能直接访问的类属性,需要通过类提供的接口进行访问,以双下划线开头的__foo代表类的私有成员,以双下划线开头和结尾的__foo__代表Python......
  • 使用Python的requests库自定义请求
    importrequestsfromrequestsimportRequest,Sessionurl="http://challenge-d590d34746e26bc5.sandbox.ctfhub.com:10800/index.php"headers={"user-agent":"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,lik......
  • python解压缩zip文件, 同时显示进度信息
    直接上代码:fromtqdmimporttqdmimportzipfiledefunzip(zipFile):'''把ZIP文件解压到以文件名命名的目录中'''#获得文件名(不含后缀),作为解压缩的目录dir_name=os.path.dirname(zipFile)#获取zip文件所在的目录名filename=os.path.basename(......
  • Python 注释:解释和优化代码可读性
    注释可以用来解释Python代码。注释可以用来使代码更易读。注释可以用来在测试代码时防止执行。创建注释注释以#开始,Python会忽略它们:示例:获取您自己的Python注释#这是一个注释print("Hello,World!")注释可以放在一行的末尾,Python会忽略行的其余部分:示例print("Hello,W......
  • python实现一个简单的背单词程序
    功能需求给定一个words.txt文档,里面存放单词及其释意,要求编写一个python程序,实现自动背刺功能:程序开始时,首先随机给用户一个单词和其释义,用户自行选择师是否记住该单词,如果选择记住的话,程序会将该单词标记为需要记忆,在接下来的操作中会继续出现这个单词,直到用户不需要记忆为止;如果......
  • 在 Windows 系统下安装和使用 PyCharm:Python 开发的得力助手
    PyCharm是一款强大的Python集成开发环境(IDE),它提供了丰富的功能和工具,可帮助开发人员更轻松地编写、调试和管理Python项目。本博客将介绍如何在Windows系统下安装和使用PyCharm,以及一些基本的使用技巧。步骤1:下载PyCharm首先,让我们从JetBrains官网下载PyCharm的最新......
  • python04
    4.3布尔类型(bool)布尔类型中共有两个值:True/Falseprint(1>2)print(False)print(1==1)print(True)name=input("请输入你的用户名:")ifname=="alex":print("用户登录成功")else:print("用户登录失败")补充:1>21==3&quo......
  • Python-day10
    #函数defadd(a,b):c=a+breturncresult=add(10,20)print(result)res=add(a=11,b=22)print(res)deffun(arg1,arg2):print('arg1',arg1)print('arg2',arg2)arg1=100arg2.append(10)print('arg1',arg1......