从内存管理的角度来看,Python语言的变量和参数传递情况解析

从内存管理的角度来看,Python语言的变量和参数传递情况解析

概述

从内存管理的角度来看,Python中的变量和参数传递有一些特点:

☆ 变量是对象的引用:在Python中,变量实际上是对象的引用,而不是对象本身。当你给一个变量赋值时,实际上是将变量指向了一个对象。这意味着变量可以指向不同类型的对象,并且可以在程序中随时改变指向的对象。

☆ 引用计数:Python使用引用计数来管理内存。每个对象都有一个引用计数,表示有多少个变量引用了该对象。当引用计数为0时,对象将被自动回收。当一个变量不再引用一个对象时,引用计数会减少。当引用计数为0时,对象的内存将被释放。

☆ 对象的可变性:Python中的对象分为可变对象和不可变对象。可变对象(如列表、字典)的值可以被修改,而不可变对象(如整数、字符串、元组)的值不能被修改。这意味着如果你修改了一个可变对象,那么所有引用这个对象的变量都会受到影响。

☆ 参数传递方式:在Python中,函数的参数传递是按值调用(call by value) 来传递的(其中的 值 始终是对象的 引用 而不是对象的值)——实际上,按对象引用调用(call by object reference)调用这种说法更好。对于不可变对象(如整数、字符串、元组),由于它们的值不能被改变,所以函数内部对这些对象的修改实际上是创建了一个新的对象。因此,函数内部的修改不会影响到函数外部的实际参数。对于可变对象(如列表、字典),由于它们的值可以被改变,所以函数内部对这些对象的修改会直接改变原始对象的值。因此,函数内部的修改会影响到函数外部的实际参数。

在Python中,id()函数用于获取对象的唯一标识符(即内存地址)。每个对象(Python语言中,所有的 数据 都被称之为 对象)在内存中都有一个唯一的标识符,可以通过id()函数来获取。

例如id(1500),它会返回整数1500的唯一标识符(内存地址)。这个标识符是一个整数值,用于唯一标识该对象在内存中的位置,类似如1878476699696,注意,这个值在不同的运行时环境中可能会有所不同,因为它取决于内存管理和对象分配的具体实现。Python的内存管理和对象分配模型是自动的,由Python的内存管理器负责。

请看如下情况:

在Python中,小整数对象(通常是-5到256之间的整数)是预先创建并重复使用的。这是为了优化内存使用和性能,因为这些小整数在大多数Python程序中都会频繁使用。所以当你创建一个变量a并赋值为2,然后创建一个变量b并赋值为2,它们实际上都是指向同一个内存对象。

对于大整数(通常是大于256的整数),Python会为每个新的整数创建一个新的对象。所以当你创建一个变量a并赋值为1500,然后创建一个变量b并赋值为1500,它们实际上是指向两个不同的内存对象。这就是为什么id(a)和id(b)返回不同的值。参见下图:

Python语言的变量和赋值情况

Python语言中,所有的 数据 都被称之为 对象。

每个整数、小数、字符串,后面要学的 字典、元组、列表 等, 都是对象。

编程语言为了方便操作数据对象,也需要给对象起一个名字,称之为 变量名 , 有时也简称 变量。

Python中的变量,就是 对象的名称。

Python中,名称 用于指代对象。 名称是通过名称绑定操作来引入的。

【见官方文档 命名与绑定

https://docs.python.org/zh-cn/3/reference/executionmodel.html#naming-and-binding

提示:在Python的官方文档中更多地使用了“名称”(name)这个术语来。但是在实际的编码和交流中,人们也常常使用“变量”(variable)这个术语来描述Python中的名称。】

Python 是一门动态类型的语言,所以我们无须预先声明变量类型,直接对变量赋值即可。

可以使用赋值语句来创建变量并使其引用一个数据。当一个变量表示存储器中的某个值时,也称这个变量引用(reference)了这个值。

赋值语句的基本格式是:

Variable = expression

等号(=)称为赋值运算符(assignment operator)。在这个基本格式中,variable 是变量名,expression 是一个值,或者能够产生一个值的代码。赋值语句执行结束后,位于等号左边的变量将引用位于等号右边的值。

提示:在给变量赋值之前是不能使用变量的。如果在变量被赋值之前就对它进行某种操作,如打印它,将导致一个错误。

【注意: Python 语言中的变量与大多数其他编程语言中的变量的工作方式不同。在大多数编程语言中,变量是保存值的内存位置。在这些编程语言中,当给变量赋值时,该值保存在变量的内存位置。而在 Python 语言中,变量是一个内存位置,它保存另一个内存位置的地址。将值赋给 Python 变量时,该值将存储在与该变量分离的内存位置。变量保存的是保存值的内存位置的地址。这就是为什么在 Python 中,不说变量“保存”一个值,而说变量“引用”一个变量。或者说,Python 中变量是代表存储在计算机存储器中的某个值的名称。】

变量之所以称为“变量”,是因为在程序执行过程中它们可以引用不同的值。下面就看看Python 中变量的赋值和再赋值情况。

创建了一个名为 dollars 的变量,并将 2.75 赋值给它

Dollars = 2.75

给变量 dollars 赋以一个新值99.95,当给变量 dollars 赋以一个新值99.95时,虽然旧值 2.75 依然保存在计算机的存储器中,但是因为没有变量引用它,所以这个值已不能再被使用。参见下图:

注意,当存储器中的值不再被变量引用时,Python 解释器将通过所谓的垃圾收集机制来进行处理,自动地将它们移出存储器。

【在python中,变量保存的是对象(值)的引用,id()函数可以获取变量在内存中的地址。在Python中,值可以放在内存的某个位置(地址),变量用于引用它们,给变量赋一个新值,原值不会被新值覆盖,变量只是引用了新值。顺便说明,Python的垃圾回收机制会自动清理不再被用到的值,所以不用担心计算机内存中充满被“丢弃”的无效的值。】

一定要牢记:在 Python 语言中,变量仅仅是引用存储器中某个数据的名字,并且可以引用任何类型的数据项。

x = 99 语句创建了名为 x 的变量,并赋给它 int 型的值 99。

将一个字符串 'Take me to your leader'赋值给变量 x时,变量 x 不再引用一个 int 型数据,而是引用字符串 'Take me to your leader'。

下面再看看这种情况:

a = 10

b = a

在上述的例子中,我们声明了一个变量 a,其值为 10,然后将 b 也指向 a,这是在内存中的布局是这样的,变量 a 和 b 会指向同一个对象 10,而不是给 b 重新生成一个新的对象。

当执行完 a = a + 10 后,因为整数是不可变对象,所以并不会将 10 变成 20,而是生成一个新的对象 20 ,然后 a 会指向这个新的对象。b 还是指向旧对象 10。

Python 允许你同时为多个变量赋值。例如:

a = b = c = 10

以面示例,创建一个整型对象,值为 10,从后向前赋值,三个变量被赋予相同的数值。

您也可以为多个对象指定多个变量。例如:

a, b, c = 10, 20, " hello"

以面示例,两个整型对象 10 和 20 的分配给变量 a 和 b,字符串对象 “hello” 分配给变量 c。

在Python中的参数传递情况

要讲清在Python中函数的参数传递,需要从Python中函数是什么讲起。

在Python中,函数是一种组织代码的方式,它将一段程序代码封装起来,以便于重复使用。函数可以接收输入参数,并返回一个或多个结果。这种封装可以使代码更加清晰、易读,也有助于代码的重用。Python提供了许多内置函数,如print()、len()等,可以直接使用。编程人员还可以自定义函数。自定义图示如下:

Python中的函数定义使用def关键字,后跟函数名、括号()和冒号。括号中可以放置函数的参数,参数之间用逗号分隔。函数的主体部分在冒号后的缩进块中定义。Python中定义函数语法如下:

def 函数名(参数列表):

    函数体

函数体由缩进的代码块组成。Python的函数体包括:

函数体包括以下几个部分:

文档字符串(docstring):文档字符串是可选的,用于描述函数的作用、参数、返回值等信息。它位于函数定义的第一行或第二行,使用三引号('''或""")括起来。文档字符串可以通过help()函数或在交互式环境中使用__doc__属性来访问。

语句(statements):函数体中可以包含任意数量的语句,用于执行具体的任务。这些语句可以是赋值语句、条件语句、循环语句等,根据函数的需求编写。

返回表达式(return expression):函数可以通过return语句返回一个值。返回值是可选的,如果没有return语句或者return后面没有表达式,函数将返回None。当函数执行到return语句时,函数将立即结束,并将返回值传递给调用函数的地方。

下面介绍python参数传递

python官方文档的说法【https://docs.python.org/zh-cn/3/tutorial/controlflow.html#defining-functions 】实参是使用 按值调用(call by value) 来传递的(其中的 值 始终是对象的 引用 而不是对象的值)——实际上,按对象引用调用(call by object reference)调用这种说法更好。具体来说:

如果传入的参数是不可变类型(如数字、字符串、元组),那么在函数体内修改参数的值,并不会影响到原来的变量。因为不可变类型的变量实际上是值的引用,当你试图改变变量的值时,相当于是在创建新的对象。例如:

def change_number(num):
    num = 100

x = 10
change_number(x)
print(x)  # 输出:10

在上面的例子中,尽管在函数内部num的值被改变了,但是原变量x的值并没有改变。参见下图:

如果传入的参数是可变类型(如列表、字典),那么在函数体内修改参数的值,会影响到原来的变量。因为可变类型的变量存储的是一个地址,当你试图改变变量的值时,实际上是在改变这个地址所指向的内容。例如:

def change_list(lst):
    lst.append(100)

x = [1, 2, 3]
change_list(x)
print(x)  # 输出:[1, 2, 3, 100]

在上面的例子中,函数内部对参数lst的修改影响到了原变量x的值。参见下图:

附录

Python变量的认识理解 https://blog.csdn.net/cnds123/article/details/116768499 
python函数 https://blog.csdn.net/cnds123/article/details/108179769

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vi vim 末尾编辑按GA 在最后一行下方新增一行编辑按Go

vim 快速跳到文件末尾 在最后一行下方新增一行 移到末尾,并且进入文本录入模式 GA (大写G大写A) 在一般模式(刚进入的模式,esc模式) GA 或 Shift ga 先 G 或 shiftg 到最后一行 然后 A 或 shifta 到本行末尾 并且进入文本录入模式 在最后一行下方新增一行 (光标换行,文字不…

【Linux】Nginx安装使用负载均衡及动静分离(前后端项目部署),前端项目打包

一、Nginx导言 1、引言 Nginx 是一款高性能的 Web 服务器和反向代理服务器,也可以充当负载均衡器、HTTP 缓存和安全防护设备。它的特点是内存占用小、稳定性高、并发性强、易于扩展,因此在互联网领域得到了广泛的使用。 总结出以下三点: 负载均衡&#x…

lvsDR模式

LVS-DR模式 是最常用的LVS负载方式 直接路由模式 Lvs调度器 只负责请求和转发 转发到真实服务器 但是响应结果 由后端服务器直接转发给客户端 不需要经过调度器处理 可以减轻Lvs调度器的负担 提高系统性能和稳定性 工作原理: 客户端发送请求到vipLVS调度器接受请求…

miniconda快速安装

目录 一、Linux下miniconda安装 1.1、安装 1.2、miniconda初始化 二、Windows下miniconda安装 三、maOS下miniconda安装 3.1、安装 3.2、miniconda初始化 四、参考: 本文给出windows、macos、linux下快速安装miniconda方法。 对比conda,minicond…

光学仿真|优化汽车内部照明体验

当我们谈论优化人类感知的内部照明时,我们实际上指的是两个重点领域:安全性和驾驶员体验。如果内部照明可以提供尽可能最佳的体验,驾驶员则能够更好地应对颇具挑战性或意外的驾驶状况,并且减轻疲劳感。除了功能优势外,…

【Servlet】 一

本文主要介绍了如何在tomcat部署一个webapp 以及 如何借助maven用servlet编写一个hello world . 一.Tomcat Tomcat是一个Java里广泛使用的http服务器 HTTP服务器有很多实现,其中最知名的是Nginx;而在Java里,最知名的是Tomcat 一个Tomcat服务…

【K8S】二进制安装

常见的K8S安装部署方式 ●Minikube Minikube是一个工具,可以在本地快速运行一个单节点微型K8S,仅用于学习、预览K8S的一些特性使用。 部署地址:https://kubernetes.io/docs/setup/minikube ●Kubeadm☆ Kubeadm也是一个工具,提…

LInux之在同一Tomcat下使用不同的端口号访问不同的项目

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《LInux实战开发》。🎯🎯 …

Vue入门——核心知识点

简介 Vue是一套用于构建用户界面的渐进式JS框架。 构建用户界面:就是将后端返回来的数据以不同的形式(例如:列表、按钮等)显示在界面上。渐进式:就是可以按需加载各种库。简单的应用只需要一个核心库即可,复杂的应用可以按照需求…

transformers-AutoClass

https://huggingface.co/docs/transformers/main/en/autoclass_tutorialhttps://huggingface.co/docs/transformers/main/en/autoclass_tutorialAutoClass可以自动推断和加载给定checkpoint的正确架构。 对于文本,使用Tokenizer将文本转换为token序列,创…

IDEA中application.properties文件中文乱码

现象: 原因: 项目编码格式与IDEA编码格式不一致导致的 解决办法: 在File->Settings->Editor->File Encodings选项中,将Global Encoding,Project Encoding,Default encoding for properties files这三个选项置为一致&a…

通过netstat命令查看Linux的端口占用

一、netstat 完整写作network statistics,简写为netstat ,常用的几个参数为l、n、t、u、p。 -l : 仅展示监听状态下的程序(state 为LISTEN)。 -n :会使用ip端口的方式,来进行地址的描述。不使用-n就会变成服务器的名称…

毕业设计基于SpringBoot+Vue智慧云办公系统源码+数据库+项目文档

智慧云办公管理系统 一、系统简介 智慧云办公系统是一个采用SpringBootVue技术开发的前后端分离的项目,云办公系统通过软件的方式,方便快捷处理中小型企业的公司日常事务,能够提高整体的管理运营水平,使得办公更加高效方便&…

随想录一刷·数组part1

你好&#xff0c;我是安然无虞。 文章目录 1. 二分查找题型2. 移除元素题型 1. 二分查找题型 二分查找传送门 class Solution { public:int search(vector<int>& nums, int target) {// 在有序数组中查找第一时间想到二分查找int left 0, right nums.size() - 1…

虚拟机部署与发布J2EE项目(Linux版本)

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.jdk安装配置 打开虚拟机 Centos 登入账号&#xff0c;并且使用MobaXterm进行连接 1.1. 传入资源 连接…

单元化架构的思考

银行业“多活”的发展历程 受监管政策的要求&#xff0c;银行一般会在同城、异地或者多地进行数据中心建设&#xff0c;以保证系统的稳定运行&#xff0c;但从目前实际情况来看&#xff0c;“同城双活”目前仍是很多银行采用的主要形式。银行业的“多活”架构在发展过程中存在三…

Stable Diffusion WebUI扩展openpose-editor如何使用

先上地址: GitHub - fkunn1326/openpose-editor: Openpose Editor for AUTOMATIC1111s stable-diffusion-webuiOpenpose Editor for AUTOMATIC1111s stable-diffusion-webui - GitHub - fkunn1326/openpose-editor: Openpose Editor for AUTOMATIC1111s stable-diffusion-webu…

高校教务系统登录页面JS分析——天津大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍天津大学教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习&#xff0c;勿用于非法用途。 一、密…

第2篇 机器学习基础 —(4)k-means聚类算法

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。聚类算法是一种无监督学习方法&#xff0c;它将数据集中的对象分成若干个组或者簇&#xff0c;使得同一组内的对象相似度较高&#xff0c;不同组之间的对象相似度较低。聚类算法可以用于数据挖掘、图像分割、文本分类等领域…

Prometheus+Grafana

一、Prometheus 获取配置文件 docker run -d -p 9090:9090 --name prometheus prom/prometheusmkdir -p /app/prometheusdocker cp prometheus:/etc/prometheus/prometheus.yml /app/prometheus/prometheus.yml停止并删除旧的容器&#xff0c;重新启动 docker run -d --name…