当前位置:首页 > 科技  > 软件

通过 Atexit 模块让 Python 实现 Golang 的 defer 功能,你学会了吗?

来源: 责编: 时间:2024-04-11 08:57:46 220观看
导读在 Go 里面可以通过 defer 语句让函数在结束时执行预定义好的一些操作,举个例子。package mainimport "fmt"func main() { defer fmt.Println("高老师总能分享出好东西") fmt.Println("执行结束") /* 执行

在 Go 里面可以通过 defer 语句让函数在结束时执行预定义好的一些操作,举个例子。wfG28资讯网——每日最新资讯28at.com

package mainimport "fmt"func main() {    defer fmt.Println("高老师总能分享出好东西")    fmt.Println("执行结束")    /*    执行结束    高老师总能分享出好东西    */}

这个功能非常方便,比如打开文件之后可以执行 defer fp.Close(),这样函数结束时会自动关闭文件句柄。那么在 Python 里面可不可以实现类似的功能呢?本次来聊一聊 atexit 模块,它能帮我们实现类似的效果。wfG28资讯网——每日最新资讯28at.com

import atexitdef exit_func(words):    print(words)# 将函数注册进去atexit.register(exit_func, "高老师总能分享出好东西")print("Hello")print("World")"""HelloWorld高老师总能分享出好东西"""

通过 atexit.register 将函数注册进去之后,会在程序结束之前执行,当然也可以同时注册多个。wfG28资讯网——每日最新资讯28at.com

import atexitdef exit_func(words):    print(words)# 将函数注册进去atexit.register(exit_func, "高老师总能分享出好东西")atexit.register(exit_func, "S 老师今年 18,单身带俩娃")atexit.register(exit_func, "只因^(* ̄(oo) ̄)^只因大(出海版)")print("Hello")print("World")"""HelloWorld只因^(* ̄(oo) ̄)^只因大(出海版)S 老师今年 18,单身带俩娃高老师总能分享出好东西"""

如果同时注册了多个函数,那么会按照先入后出的顺序执行。非常简单,其实 atexit 模块就是将我们注册的函数保存在了一个数组中,程序结束的时候,从后往前依次执行。wfG28资讯网——每日最新资讯28at.com

图片图片wfG28资讯网——每日最新资讯28at.com

既然可以注册函数,那么也可以取消注册。wfG28资讯网——每日最新资讯28at.com

import atexitdef exit_func1(words):    print(words)def exit_func2(words):    print(words)atexit.register(exit_func1, "高老师总能分享出好东西")atexit.register(exit_func1, "S 老师今年 18,单身带俩娃")atexit.register(exit_func2, "只因^(* ̄(oo) ̄)^只因大(出海版)")# 取消注册,所有注册的 exit_func1 函数都会被删除atexit.unregister(exit_func1)"""只因^(* ̄(oo) ̄)^只因大(出海版)"""

而它的逻辑也很简单,就是遍历数组,如果和指定的函数相等,那么就删掉。我们看一下源代码。wfG28资讯网——每日最新资讯28at.com

图片图片wfG28资讯网——每日最新资讯28at.com

如果你想将注册的函数全部取消掉,那么也可以调用 _clear() 函数。wfG28资讯网——每日最新资讯28at.com

import atexitdef exit_func1(words):    print(words)def exit_func2(words):    print(words)atexit.register(exit_func1, "高老师总能分享出好东西")atexit.register(exit_func1, "S 老师今年 18,单身带俩娃")atexit.register(exit_func2, "只因^(* ̄(oo) ̄)^只因大(出海版)")atexit._clear()

此时程序不会有任何输出,因为注册的函数全部被清空了,同样可以看一下它的源代码。wfG28资讯网——每日最新资讯28at.com

图片图片wfG28资讯网——每日最新资讯28at.com

最后就是函数的调用时机,我们注册的函数在程序结束时才会调用,可不可以让它们在任意时刻调用呢?wfG28资讯网——每日最新资讯28at.com

import atexitdef exit_func1(words):    print(words)def exit_func2(words):    print(words)atexit.register(exit_func1, "AAA")atexit.register(exit_func1, "BBB")# 调用注册的函数,调用之后函数会被删除atexit._run_exitfuncs()print("++++++++++++++++")atexit.register(exit_func2, "CCC")atexit._run_exitfuncs()print("----------------")"""BBBAAA++++++++++++++++CCC----------------"""

输出结果表明,一旦调用了 _run_exitfuncs,所有注册的函数会立即被调用。我们看一下源代码。wfG28资讯网——每日最新资讯28at.com

图片图片wfG28资讯网——每日最新资讯28at.com

以上就是 atexit 模块的用法,那我们如何基于它实现 Golang 的 defer 呢?wfG28资讯网——每日最新资讯28at.com

from typing import Callableimport atexitdef defer(func: Callable, *args, **kwargs):    atexit.register(func, *args, **kwargs)def get_file_content(file_path):    fp = open(file_path, encoding="utf-8")    defer(fp.close)  # 注册函数    content = fp.read()    # do something    ...    atexit._run_exitfuncs()  # 触发注册函数执行get_file_content("config.py")

不过这个例子明显有点刻意了,因为必须要在函数的结尾调用 atexit._run_exitfuncs,而之所以要实现 Go 的 defer,就是为了避免遗忘某些逻辑。wfG28资讯网——每日最新资讯28at.com

如果每次都要在函数结尾调用 atexit._run_exitfuncs,那还不如不用,于是我们可以考虑使用装饰器。wfG28资讯网——每日最新资讯28at.com

from typing import Callablefrom functools import wrapsimport atexitdef defer(func: Callable, *args, **kwargs):    atexit.register(func, *args, **kwargs)# 给函数赋予 defer 功能def enable_defer(func):    @wraps(func)    def inner(*args, **kwargs):        ret = func(*args, **kwargs)        atexit._run_exitfuncs()        return ret    return inner@enable_defer  # 通过装饰器,让函数支持 defer 功能def get_file_content(file_path):    fp = open(file_path, encoding="utf-8")    # 注册函数    defer(fp.close)    defer(print, "get_file_content 函数实现了 defer 功能")    content = fp.read()    print("函数执行结束")get_file_content("config.py")print("程序结束")"""函数执行结束get_file_content 函数实现了 defer 功能程序结束"""

输出结果表明,在函数结束后,通过 defer 注册的函数执行了。wfG28资讯网——每日最新资讯28at.com

以上就是用 Python 实现 Go 的 defer,不过在工作中还是不建议这么做,没啥必要,这里只是想分享一下 atexit 模块。wfG28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-82736-0.html通过 Atexit 模块让 Python 实现 Golang 的 defer 功能,你学会了吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 不只是搜索 细看三星 Galaxy S24 系列即圈即搜功能

下一篇: 如何在JavaScript中复制一个对象?

标签:
  • 热门焦点
  • MIX Fold3包装盒泄露 新机本月登场

    小米的全新折叠屏旗舰MIX Fold3将于本月发布,近日该机的真机包装盒在网上泄露。从图上来看,新的MIX Fold3包装盒在外观设计方面延续了之前的方案,变化不大,这也是目前小米旗舰
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • 一个注解实现接口幂等,这样才优雅!

    场景码猿慢病云管理系统中其实高并发的场景不是很多,没有必要每个接口都去考虑并发高的场景,比如添加住院患者的这个接口,具体的业务代码就不贴了,业务伪代码如下:图片上述代码有
  • 零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • ESG的面子与里子

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之三伏大幕拉起,各地高温预警不绝,但处于厄尔尼诺大“烤”之下的除了众生,还有各大企业发布的ESG报告。ESG是“环境保
  • 2299元起!iQOO Pad明晚首销:性能最强天玑平板

    5月23日,iQOO如期举行了新品发布会,除了首发安卓最强旗舰处理器的iQOO Neo8系列新机外,还在发布会上推出了旗下首款平板电脑——iQOO Pad,其最大的卖点
  • iQOO Neo8 Pro抢先上架:首发天玑9200+ 安卓性能之王

    经过了一段时间的密集爆料,昨日iQOO官方如期对外宣布:将于5月23日推出全新的iQOO Neo8系列新品,官方称这是一款拥有旗舰级性能调校的作品。随着发布时
  • OPPO K11搭载高性能石墨散热系统:旗舰同款 性能凉爽释放

    日前OPPO官方宣布,将于7月25日14:30举办新品发布会,届时全新的OPPO K11将正式与大家见面,将主打旗舰影像,和同档位竞品相比,其最大的卖点就是将配备索尼
  • DRAM存储器10月价格下跌,NAND闪存本月价格与上月持平

    10月30日,据韩国媒体消息,自今年年初以来一直在上涨的 DRAM 存储器的交易价格仅在本月就下跌了近 10%,此次是全年首次降价,而NAND 闪存本月价格与上月持平。市
Top