Python对象作为参数传递到函数/方法的机制

news2024/11/15 15:48:12

以代码为例 

class Person:
    name = None
    age = None

# 分析对象作为参数传递到函数/方法的机制
def f1(person):
    print(f"2. person的地址:{id(person)}")
    person.name = "james"
    person.age += 1

p1 = Person()

p1.name = "jordan"
p1.age = 21
print(f"1. p1的地址: {id(p1)} ,p1.name: {p1.name} ,p1.age: {p1.age}")
f1(p1)
print(f"3. p1的地址: {id(p1)} ,p1.name: {p1.name} ,p1.age: {p1.age}")

代码理论分析

        我们先创建了一个Person类,类中有两个属性,分别为name属性和age属性,随后在Person类外创建了一个 f1 函数。

        随后通过执行下述代码创建了一个对象p1,

p1 = Person()

相当于在我们的主栈区有了p1对象,这个p1指向数据区的一个空间,假设该空间的地址为0x1122。

接下来执行

p1.name = "jordan"
p1.age = 21

代码,即我们给p1对象的name属性赋值为“jordan”,给age属性赋值为21,那么我们的内存图应如下所示。

接下来,执行

print(f"1. p1的地址: {id(p1)} ,p1.name: {p1.name} ,p1.age: {p1.age}")

语句,根据上面的内存图可知,p1对象的id为0x1122,p1对象的name属性值为jordan,p1对象的age属性值为21。输出控制台得到如下所示。

        紧接着,程序执行

f1(p1)

代码,调用 f1 函数,这个时候它相当于开了一个新栈,此时将p1作为实际参数赋给形式参数person,那么在新栈中,相当于有一个person对象,那么该person对象指向数据区的哪个空间呢?
        我们知道,对象传参本质是传递引用,就相当于person对象也指向0x1122这个数据空间,如下图所示。

        接下来,执行f1函数中的print语句,该语句要输出person的地址,这个person地址与前面的p1对象地址是一样的,则该语句输出结果为:0x1122。

接下来,执行f1函数中的下面两条语句:

 person.name = "james"
 person.age += 1

        通过person对象修改name、age属性的值,name属性的值原先是jordan,修改后为james,age属性的值原先是21,修改后为22,过程如下图所示。

 上述流程执行结束后,程序返回主栈继续执行剩余的代码,即最后一行代码,如下所示。

print(f"3. p1的地址: {id(p1)} ,p1.name: {p1.name} ,p1.age: {p1.age}")

        我们由内存图可以得知,p1对象的id值没有变化,仍然是0x1122,但p1的name属性、age属性均被改变,p1.name为james,p1.age为22。 程序最终输出结果如下图所示。

我们运行我们的程序,得到如下结果:

1. p1的地址: 1769002692360 ,p1.name: jordan ,p1.age: 21
2. person的地址:1769002692360
3. p1的地址: 1769002692360 ,p1.name: james ,p1.age: 22

注意:地址不唯一,但地址都是一样的。

编译器验证

        接下来,我们使用实际的编译器演示上述流程,来验证我们的分析是否正确。代码如下所示,11行至27行,我们在第21行打上断点,用以测试。

        开始调试,点击调试按钮,程序执行到第20行停止,此时还没有执行到第21行,故此时p1对象是不存在的。函数f1位于的内存地址是:<function f1 at 0x0000016ED4E1F048>

        接下来我们Step Into或按F7逐步调试。 得到如下结果,我们发现,此时p1对象被创建,地址是:p1: <__main__.Person object at 0x0000016ED4E16DC8>

观察变量区:

p1对象被创建,p1的两个属性age和name值均为None。

        再按两次Step Into,为p1对象的name属性及age属性赋值,得到如下结果,p1对象的name属性被赋值为jordan,age属性被赋值为21。 
 

再按下Step Into,程序将会执行第25行的打印语句,程序输出:

        再按下Step Into,程序将会执行第26行语句 ,进入到函数f1中(进入新栈),注意此时的person对象地址为:<__main__.Person object at 0x0000016ED4E16DC8>,与前面的p1对象地址一致,如下图所示。

观察数据区,person对象的name属性为jordan,age属性为21。

再按下Step Into,程序将执行第17行,打印person对象的地址,如下图所示。 
 

再按下Step Into,程序执行第18行代码,借助person对象修改name属性为james,如下图所示。 

         再按下Step Into,程序执行第19行代码,借助person对象修改age属性为22,并返回主栈,如下图所示。

        最后,程序执行最后一行代码,即第27行代码,打印p1对象的地址,name属性,age属性。最终结果如下图所示。 

 至此,整个执行流程到此结束,我们发现,编译器验证步骤与我们分析的一致。

总结

        当对象作为参数在函数或者方法中进行传递的时候(函数或方法中会修改对象的属性值),那么最终会影响到对象的属性值。

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

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

相关文章

24计算机考研调剂 | 【官方】桂林理工大学(11自命题、22自命题)

桂林理工大学信息工程与科学学院招收调剂 考研调剂补充信息 一、招收专业 计算机科学与技术&#xff08;学硕&#xff09;、软件工程&#xff08;学硕&#xff09;、计算机技术&#xff08;专硕&#xff09;、人工智能&#xff08;专硕&#xff09;、软件工程&#xff08;专…

使用 Python 编写网络爬虫:从入门到实战

网络爬虫是一种自动化获取网页信息的程序&#xff0c;通常用于数据采集、信息监控等领域。Python 是一种广泛应用于网络爬虫开发的编程语言&#xff0c;具有丰富的库和框架来简化爬虫的编写和执行过程。本文将介绍如何使用 Python 编写网络爬虫&#xff0c;包括基本原理、常用库…

C语言之我对结构体与联合体的认识

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

APP广告变现初期,广告测试怎么做?

广告变现能给应用带来收入增长的一条非常有效的途径&#xff0c;同时可以帮助变现困难的产品类型最快实现盈利&#xff0c;例如付费下载、工具类产品等。 广告测试是APP广告变现中必不可少的一步&#xff0c;广告测试可以用来验证增减广告位会不会引起用户反感、对接广告平台能…

如何解决MySQL死锁(看懂MySQL锁日志)

有时候系统在生产运行着&#xff0c;会突然爆出 [40001][1213] Deadlock found when trying to get lock; try restarting transaction 这个时候每个人都会很紧张&#xff0c;因为死锁会影响DB性能&#xff0c;严重时甚至拖垮整个系统。在实际的环境中&#xff0c;很多服务会共…

JMeter压测SpringBoot项目

压力测试架构图如下: 配置JMeter 在JMeter的bin目录,双击jmeter.bat 新建一个测试计划,并右键添加线程组: 进行配置 一共会发生4万次请求。 ctrl + s保存; 添加http请求: 配置http请求: 配置断言,来判断当前请求是否成功: 正常响应如下:

EtherCAT开源主站 IGH 介绍及主站伺服控制过程

目录 前言 IGH EtherCAT主站介绍 主要特点和功能 使用场景 SOEM 主站介绍 SOEM 的特点和功能 SOEM 的使用场景 IGH 主站 和 SOEM对比 1. 功能和复杂性 2. 资源消耗和移植性 3. 使用场景 EtherCAT 通信原理 EtherCAT主站控制伺服过程 位置规划模式 原点复归模式…

金融知识分享系列之:ATR指标

金融知识分享系列之&#xff1a;ATR指标 一、ATR指标二、指标原理三、海龟交易法应用1.计算开仓数量2.制定止损/加仓规则 四、ATR指标总结 一、ATR指标 利用ATR指标计算仓位&#xff0c;设置止损的规则名称&#xff1a;平均真实波动幅度参数&#xff1a;(默认14)组成&#xff…

CMeet系列技术生态沙龙---《探索未来:生成式AI赋能千行百业·杭州》

当前数字化浪潮下&#xff0c;生成式AI技术正成为推动产业升级、提升竞争力的关键力量。为深入探索未来AI技术的赋能作用&#xff0c;促进技术生态的繁荣与发展&#xff0c;CSDN-CMeet系列沙龙活动旨在搭建一个交流与探索的平台&#xff0c;通过分享前沿研究成果和应用案例&…

OpenCV实现OCR图片文本检测

一、操作步骤 把左边这样的图片&#xff0c;通过仿射变换转换成右边那样的图片。 然后再通过pytesseract读取图片内容得到图片中的文本就好了。 需要使用到&#xff1a; 仿射变换ocr识别 注&#xff1a;本文使用现成图片&#xff0c;轮廓检测较为明显&#xff0c;若是自己拍…

Css 样式记录

实现两栏布局如图所示样式&#xff1a; 方法1&#xff1a; <div style"display: flex; justify-content: space-between; width:100%;"> <div>1</div> <div>2</div> </div> 方法2&#xff1a; <div style"display: fle…

pytest ui自动化

chromedriver.exe 要对应已安装的chrome版本号

大数据面试题 —— Zookeeper

目录 ZooKeeper 的定义ZooKeeper 的特点ZooKeeper 的应用场景你觉得Zookeeper比较重要的功能ZooKeeper 的选举机制 ***zookeeper主节点故障&#xff0c;如何重新选举&#xff1f;ZooKeeper 的监听原理 ***zookeeper集群的节点数为什么建议奇数台 ***ZooKeeper 的部署方式有哪几…

C语言种sizeof()和strlen的区别

sizeof 是 C 语言内置的操作符关键字&#xff0c;而 strlen 是 C 语言库函数&#xff1b; sizeof 仅用于计算数据类型的大小或者变量的大小&#xff0c;而 strlen 只能以结尾为 \0 的字符串作为参数&#xff1b; 编译器在编译时就计算出了 sizeof 的结果&#xff0c;而 strlen …

02_设计模式

文章目录 设计模式设计模式分类UML类图设计模式的原则 常用设计模式创建型设计模式单例设计模式饿汉模式懒汉模式&#xff08;线程不安全&#xff09;懒汉模式&#xff08;线程安全&#xff09;- Synchronized懒汉模式&#xff08;线程安全&#xff09;- Double Check懒汉模式&…

Android 系统源码快速入门

Android源码快速入门 今天分享的内容是Android源码快速入门&#xff0c;主要分为以下几个步骤&#xff1a; * 硬件要求 * 虚拟机安装 * 开发环境搭建 * 下载编译源码 * 从一个简单的实际开发需求体验 Framework 开发硬件要求 用于 Android Framework 开发的电脑需要较强的 C…

算法沉淀——贪心算法二(leetcode真题剖析)

算法沉淀——贪心算法二 01.最长递增子序列02.递增的三元子序列03.最长连续递增序列04.买卖股票的最佳时机 01.最长递增子序列 题目链接&#xff1a;https://leetcode.cn/problems/longest-increasing-subsequence/ 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子…

【第十一章】改进神经网络学习方式-Softmax

我们将主要使用交叉熵成本来解决学习减速的问题。然而&#xff0c;我想简要描述另一种解决方法&#xff0c;基于所谓的 softmax 层神经元。在本章的剩余部分&#xff0c;我们实际上不会使用 softmax 层&#xff0c;因此如果你时间紧迫&#xff0c;可以跳到下一节。然而&#xf…

Vue3 依赖注入provide与inject

简介 关于provide与inject下面是vue官网上的一些介绍 通常情况下&#xff0c;当我们需要从父组件向子组件传递数据时&#xff0c;会使用props。想象一下这样的结构&#xff1a;有一些多层级嵌套的组件&#xff0c;形成了一颗巨大的组件树&#xff0c;而某个深层的子组件需要一个…

【Flask开发实战】防火墙配置文件解析(二)之shell读取内容

一、前言 上一篇文章中&#xff0c;介绍了防火墙配置文件包含的基本元素和格式样式&#xff0c;并模拟了几组有代表性的规则内容&#xff0c;作为基础测试数据。在拿到基础测试数据后&#xff0c;关于我们最终想解析成的数据是什么样式的&#xff0c;其实不难看出&#xff0c;…