关于python变量的引用以及在底层存储原理
作者:涤生手记 发布时间:2021-06-24 07:37:35
目录
1.变量的引用的底层原理
2.变量的分类
Python的变量,简单来说有数值型,布尔型,字符串类型,列表,元组,字典等6大类。那么不同变量类型在底层是如何存储的,关系到变量的引用,能否正确的掌握变量的相关操作
下面v1,v2的值分别是多少?为什么?
v1 =3
v2=v1
print("v2:",v2)
v1 += 2
print("v1:",v1)
print("v2:",v2)
#下面l2的值又是多少?为什么?
l1 = [1,2,3]
l2 =l1
print(l2)
l1.append(4)
print(l2)
1.变量的引用的底层原理
v1 =3
v2=v1
print("v2:",v2)
v1 += 2
print("v1:",v1)
print("v2:",v2) #v1的值变化了,为什么v2的值没有跟着变化呢?
'''
执行结果如下:
v1: 5
v2: 3
'''
l1 = [1,2,3]
l2 =l1
print(l2)
l1.append(4)
print(l2) #l1的值变化了,但是为什么l2的值也跟着变化了。
'''
执行结果如下:
[1, 2, 3]
[1, 2, 3, 4]'''
要点分析:
可变对象和不可变对象:不可变对象包括
int
,float
,string
,tuple
等。可变对象包括list,dict,自定义类的实例等。在
python
中通过= 复制的变量,都是同时即把变量的值,也把变量在内存中的地址复制也过去了。即=复制过的变量不仅内存地址一样,变量的值也一样。但是需要注意的是:对于不可变类型(如int)的变量,如果要更改变量的值,则会创建一个新值,并且给这个新值分配一个新的内存地址,然后把变量指向这个新值的内存地址上,而旧值如果没有被引用就等待垃圾回收。如果是可变类型变量。如果修改变量的值,则可以直接修改变量的值,变量的引用地址不会变。
不可变类型:变量赋值 a=5
后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
可变类型:变量赋值 la=[1,2,3,4]
后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
本质是因为不可变对象一旦新建后,系统就会根据他的大小给他分配固定死的内存,所以不允许修改,只修改值只能申请新的内存和地址。而可变对象,他的内存大小可以随着值的变化而自动扩容
代码分析演示:
因为变量在内存中新建时,系统都会给他分配一个地址,然后通过地址去查找或引用他的值。 Python的所有变量其实都是指向内存中的对象的一个指针,都是值的引用
代码演示1:
v1 =3
v2=v1
print("v1在内存的地址:%d,v2在内存中地址:%d"%(id(v1),id(v2)))
v1 += 2
print("v1在内存的地址:%d,v2在内存中地址:%d"%(id(v1),id(v2)))
print("v1:",v1)
print("v2:",v2)
========================================================
v1在内存的地址:1747378992,v2在内存中地址:1747378992
v1在内存的地址:1747379024,v2在内存中地址:1747378992
v1: 5
v2: 3
'''
因为:v1,v2都是int,为不可变对象,所以一旦修改他们的值,包扣加减乘除赋值等操作,系统会在内存中给他们重新创建一个。
然后再把这个变量绑定(通过地址引用)到这个值上,所以v1 +=2后,他在内存中的地址变了。而v2依旧引用的是之前的地址,所以v2的值
没有更新。
'''
代码演示2:
l1 = [1,2,3]
l2 =l1
print("l1在内存的地址:%d,l2在内存中地址:%d"%(id(l1),id(l2)))
print(l2)
print("l1在内存的地址:%d,l2在内存中地址:%d"%(id(l1),id(l2)))
l1.append(4)
print(l2)
print("l1在内存的地址:%d"%(id(l1)))
=======================================================
l1在内存的地址:37345880,l2在内存中地址:37345880
[1, 2, 3]
l1在内存的地址:37345880,l2在内存中地址:37345880
[1, 2, 3, 4]
l1在内存的地址:37345880
对于可变对象如列表,l1,l2,当修改他们的值时,系统会自动在原地址上给他们扩容内存,所以不用修改地址。
代码演示3:同理字符串等不可变的变量引用效果也一样。
str1 ='hahhahah'
str2 = str1
str1 += "123"
print(str1,str2)
hahhahah123 hahhahah
2.变量的分类
可变类型与不可变类型
可变类型,值可以改变:
列表
list
字典
dict
不可变类型,值不可以改变:
数值类型
int
,long
,bool
,float
字符串
str
元组
tuple
来源:https://blog.csdn.net/qq_26442553/article/details/81559023


猜你喜欢
- 英文文档:eval(expression, globals=None, locals=None)The arguments are a st
- 对dataframe绘图并保存:ax = df.plot() fig = ax.get_figure()fig.savefig('f
- SQL Server如何通过SQL语句直接操作另一个SQL SERVER的数据1、 现在执行SQL语句的数据库服务器开启Ad Hoc Dis
- 本文实例讲述了Python实现迭代时使用索引的方法。分享给大家供大家参考,具体如下:索引迭代Python中,迭代永远是取出元素本身,而非元素
- 第一步 去高德地图开放平台申请密钥 高德地图开放平台第二部 在vue-cli项目目录结构 里面多了config文件夹和
- <html> <head> <title> IE9 亲测JS各种去空格大全 </title>
- 例如:将日期格式为2009-6-8的转换为2009-06-08,给小于10的数字补上一个0方法一:year(now)
- datetime的astimezone设置时区遇到的坑datetime有四个主要的模块:1、date 处理年、月、日。2、time 处理时、
- 本文实例讲述了Python实现堆排序的方法。分享给大家供大家参考,具体如下:堆排序作是基本排序方法的一种,类似于合并排序而不像插入排序,它的
- 有时候想为我们的网页提供多语言支持,如果一种语言用一张网页来做实在太麻烦了,幸好Google提供了语言工具功能,下面介绍如何利用它来实现网页
- Python从MySQL数据库中导出csv文件处理csv文件导入MySQL数据库import pymysqlimport csvimport
- 格式化字符串是什么?Python字符串的格式化处理主要是用来将变量(对象)的值填充到字符串中,在字符串中解析Python表达式,对字符串进行
- 如下所示:#!/usr/bin/env python#coding: utf8import getpassdb = {}def newUse
- 本文实例讲述了Python SVM(支持向量机)实现方法。分享给大家供大家参考,具体如下:运行环境Pyhton3numpy(科学计算包)ma
- 问题python中 import ** 成功,但是不能调用它的函数或者属性,如下图所示 原因log 和 setting 在pyth
- webconfig配置:<connectionStrings> <add name="MS
- ♩ 背景昨天在自己的 Laravel5.5 框架项目中,希望集成 Layer 的图片上传功能 但是在 ajax(POST) 提交请求时,一直
- 前言:在数据库中,数据表是数据库中最重要、最基本的操作对象,是数据存储的基本单位。数据表被定义为列的集合,数据在表中是按照行和列的格式来存储
- 之前有群友反应同事给了他一个几百MB的sql脚本,导入数据库再从数据库读取数据有点慢,想了解下有没有可以直接读取sql脚本到pandas的方
- 使用PyTorch进行训练和测试时一定注意要把实例化的model指定train/eval,eval()时,框架会自动把BN和DropOut固