Python 字节码指令 LOAD_DEREF

LOAD_DEREF 是 Python 字节码指令,它与闭包和嵌套函数有关。要理解 LOAD_DEREF,我们首先需要了解 Python 中的几个概念:cellfree variable 和闭包。

  1. Cell 和 Free Variables:
    当一个嵌套函数引用了其上级作用域中的一个变量,但该变量并不是全局的或局部的,那么这个变量就被称为 free variablecell 是一个内部机制,用于存储这些 free variables,使嵌套函数可以访问它们,即使上级函数已经退出。

  2. 闭包 (Closure):
    在 Python 中,函数是一等对象,这意味着它们可以作为参数传递,可以返回,可以定义在另一个函数内部等。当内部函数引用了外部函数的变量时,我们得到了一个闭包。闭包捕获并保存了外部函数的 free variables,使得这些变量即使在外部函数结束后仍然可以被访问。

LOAD_DEREF 指令就是在闭包中使用的,用于加载从一个 cellfree variable 中的值到栈上。具体来说,它用于加载由 cell 或嵌套函数作用域中的局部变量表示的值。

让我们看一个简单的示例:

def outer(x):def inner():return xreturn innerfunc = outer(10)
print(func())  # 输出: 10

在上述示例中,inner 函数是一个闭包,因为它引用了外部函数 outer 的变量 x。当我们调用 outer 并返回 inner 时,变量 x 的值仍然被保存下来,这就是通过 cell 机制实现的。当 inner 函数执行并尝试访问 x 时,就会使用 LOAD_DEREF 指令。

如果你查看 inner 函数的字节码,你会看到 LOAD_DEREF 指令。这可以通过以下方式完成:

import dis
dis.dis(func)

在如下输出中,我们看到 LOAD_DEREF 指令,表示它正在从一个 cellfree variable 加载一个值。

  6           0 LOAD_DEREF               0 (x)2 RETURN_VALUE

接下来,让我们看看 free variablecell 的例子。

  1. Free Variable:

    free variable 是一个在嵌套函数内部被引用,但不是这个嵌套函数的局部变量,也不是全局变量的变量。在以下示例中,x 就是一个 free variable 对于 inner 函数来说。

    def outer():x = 10  # 这里的 x 就是一个 free variable 对于 inner 来说def inner():print(x)  # x 在这里被引用,但它既不是 inner 的局部变量,也不是一个全局变量inner()outer()  # 输出: 10
    
  2. Cell:

    当我们谈论闭包时,Python 使用 cell 对象来实现这个特性。这是因为,尽管上层函数已经执行完毕并退出了,但嵌套的函数依然可以访问上层函数的变量。这就是通过将这些变量保存在 cell 对象中来实现的。

    在以下示例中,我们创建了一个闭包,然后使用 __closure__ 属性来查看这些 cell 对象:

    def outer(x):def inner():return xreturn innerclosure_function = outer(25)
    print(closure_function())  # 输出: 25# 查看 closure_function 的 cell 对象
    cell = closure_function.__closure__[0]
    print(cell.cell_contents)  # 输出: 25
    

    cell 对象有一个属性 cell_contents,它保存了闭包中被引用的变量的当前值。在上面的例子中,cell.cell_contents 的值是 25,这是我们传递给 outer 函数的值。

    【注】:print(closure_function._ _closure _ _) 的输出为 (<cell at 0x00000223E8C3A6B0: int object at 0x00000223E8AD03F0>,)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/40809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大数据Hive】hive 事务表使用详解

目录 一、前言 二、Hive事务背景知识 hive事务实现原理 hive事务原理之 —— delta文件夹命名格式 _orc_acid_version 说明 bucket_00000 合并器(Compactor) 二、Hive事务使用限制 参数设置 客户端参数设置 客户端参数设置 三、Hive事务使用操作演示 操作步骤 客…

(已解决)redis.get报错com.alibaba.fastjson.JSONException: autoType is not support

redis存取值问题&#xff0c;存自定义实体对象&#xff1b; 第一次取的时候报错&#xff1a;com.alibaba.fastjson.JSONException: autoType is not support。 GenericFastJsonRedisSerializer序列化和反序列化redis的value值&#xff0c;需要bean对象含有无参构造方法。 解决…

【C语言】回调函数,qsort排序函数的使用和自己实现,超详解

文章目录 前言一、回调函数是什么二、回调函数的使用1.使用标准库中的qsort函数2.利用qsort函数对结构体数组进行排序 三、实现qsort函数总结 先记录一下访问量突破2000啦&#xff0c;谢谢大家支持&#xff01;&#xff01;&#xff01; 这里是上期指针进阶链接&#xff0c;方便…

金融术语总结

洗钱 将犯罪或其他非法违法行为所获得的违法收入&#xff0c;通过各种手段掩饰、隐瞒、转化&#xff0c;使其在形式上合法化的行为。 存量客户 某个时间段里原先已有的客户,与新增客户相对应。 月活跃用户数量&#xff0c;MAU&#xff08;Monthly Active User&#xff0c;M…

【go语言基础】go中的方法

先思考一个问题&#xff0c;什么是方法&#xff0c;什么是函数&#xff1f; 方法是从属于某个结构体或者非结构体的。在func这个关键字和方法名中间加了一个特殊的接收器类型&#xff0c;这个接收器可以是结构体类型的或者是非结构体类型的。从属的结构体获取该方法。 函数则…

【100天精通python】Day37:GUI界面编程_PyQT从入门到实战(上)

目录 专栏导读 1 PyQt6 简介&#xff1a; 1.1 安装 PyQt6 和相关工具&#xff1a; 1.2 PyQt6 基础知识&#xff1a; 1.2.1 Qt 的基本概念和组件&#xff1a; 1.2.2 创建和使用 Qt 窗口、标签、按钮等基本组件 1.2.3 布局管理器&#xff1a;垂直布局、水平布局、网格布局…

typedef函数代码段解释以及部分Windows下的系统函数

文章目录 1、typedef int (WINAPI* LPSDOLInitialize)(const SDOLAppInfo* pAppInfo)2、typedef int (WINAPI* LPSDOLGetModule)(REFIID riid, void** intf)3、typedef int (WINAPI* LPSDOLTerminal)();4、GetProcAddress运行时获取一个动态链接库&#xff08;DLL&#xff09;中…

mysql与redis区别

mysql和redis的数据库类型 mysql是关系型数据库&#xff0c;主要用于存放持久化数据&#xff0c;将数据存储在硬盘中&#xff0c;读取速度较慢。 redis是NOSQL&#xff0c;即非关系型数据库&#xff0c;也是缓存数据库&#xff0c;即将数据存储在缓存中&#xff0c;缓存的读取速…

网络

mcq Java 传输层&#xff1a;拆分和组装&#xff0c;完成端到端的消息传递&#xff0c;流量控制&#xff0c;差错控制等 网络层&#xff1a; 寻址、路由&#xff0c;复用&#xff0c;拥塞控制&#xff0c;完成源到宿的传递。 显然A选项是错误的&#xff0c;有流量控制的是传输层…

JavaScript TypeScript

文章目录 JavaScript语法事件处理与HTML和CSS集成前端框架和库 TypeScript静态类型检查语法更好的可维护性 包管理工具npmpnpmyarnBower JavaScript JavaScript&#xff08;简称JS&#xff09;是一种广泛应用于网页开发的脚本语言。它被用来为网页增加交互性和动态功能。以下是…

netty学习分享(一)

TCP与UDP TCP 是面向连接的、可靠的流协议&#xff0c;通过三次握手建立连接&#xff0c;通讯完成时要拆除连接。 UDP是面向无连接的通讯协议&#xff0c;UDP通讯时不需要接收方确认&#xff0c;属于不可靠的传输&#xff0c;可能会出现丢包现象 端口号&#xff1a; 端口号用…

【微信小程序】记一次自定义微信小程序组件的思路

最近来个需求&#xff0c;要求给小程序的 modal 增加个关闭按钮&#xff0c;上网一查发现原来 2018 年就有人给出解决方案了&#xff0c;于是总结下微信小程序自定义组件的思路&#xff1a;一句话&#xff0c;用 wxml css实现和原生组件类似的样式和效果&#xff0c;之后用 JS…

【uniapp】uniapp设置安全区域:

文章目录 一、效果图:二、实现代码: 一、效果图: 二、实现代码: {"path": "pages/index/index","style": {"navigationStyle": "custom","navigationBarTextStyle": "white","navigationBarTitle…

消息队列学习笔记

消息队列基础 适合消息队列解决的问题 异步处理&#xff1a;处理完关键步骤后直接返回结果&#xff0c;后续放入队列慢慢处理流量控制&#xff1a; 使用消息队列隔离网关和后端服务&#xff0c;以达到流量控制和保护后端服务的目的。能根据下游的处理能力自动调节流量&#x…

leetcode做题笔记79单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相…

Matlab工具NIFTI包的基本功能函数

Matlab工具NIFTI包的基本功能函数 Nifti 格式最初是为神经影像学发明的。神经影像信息学技术计划&#xff08;NIFTI&#xff09;将 NIfTI 格式预设为 ANALYZE7.5 格式的替代品。它最初的应用领域是神经影像&#xff0c;但是也被用在其他领域。这种格式的主要特点就是它包含两个…

Docker基础入门:常规软件安装与镜像加载原理

Docker基础入门&#xff1a;常规软件安装与镜像加载原理 一、Docker常规软件安装1.1、部署nginx1.2、部署tomcat1.3、部署elasticsearch1.4、如何部署kibana-->连接elasticsearch1.5、部署可视化工具 二、 镜像加载原理2.1、镜像是什么2.2、Docker镜像加速原理2.3、分层理解…

为什么我的集群一个 Spark Executor / Yarn Container 只分配一个vCore?

在很多集群里,在关闭了Spark的DynamicAllocation的前提下(避免自动申请空闲资源,干扰测试结果),都会观察到:提交Spark作业时,申请 1 个 driver + n 个 executor 会在Yarn上对应创建 n+1 个 container,但是每个container只有一个vCore,通过--driver-cores和--executor-…

Grafana Prometheus 通过JMX监控kafka 【2023最新方式】

第三方kafka exporter方案 目前网上关于使用Prometheus 监控kafka的大部分资料都是使用一个第三方的 kafka exporter&#xff0c;他的原理大概就是启动一个kafka客户端&#xff0c;获取kafka服务器的信息&#xff0c;然后提供一些metric接口供Prometheus使用&#xff0c;随意它…

docker 安装mysql8.0

1、拉取镜像 docker pull mysql2、运行镜像 docker run -d --restartalways --name mysql --privilegedtrue -p 3306:3306 -v /home/sunyuhua/docker/mysql/data:/var/lib/mysql -v /home/sunyuhua/docker/mysql/conf:/etc/mysql/conf.d -v /home/sunyuhua/docker/mysql/logs…