Python 可变类型和不可变类型及引用过程解析

在Python中定义一个数据便在内存中开辟一片空间来存储这个变量的值,这块已经被分配的内存空间便会有一个内存地址。访问这块内存需要用到变量名,变量名实际存储的是变量的地址在内存中的地址,但是使用print()函数得到的确实这块内存中实际的地址。这个就当成规定就好,没必要纠结。

获得变量在内存中的地址,可以使用id()函数。

常规使用

变量之间的赋值其实是把一个变量的内存地址传递给另一个变量,这样两个变量便都指向内存中的同一块空间,因此这两个变量的之是相等的

a = 1
b = a
print("a:%d  b:%d" % (a,b))
print(id(a))
print(id(b))
结果:
a:1  b:1
1711072016

此时如果有第三个变量c的值与a的相等,那么c的地址与a的地址一样。这一点请大家牢记。

a = 1
c = 1
print("a:%d  c:%d" % (a,c))
print(id(a))
print(id(c))
结果:
a:1  c:1
1711072016

此时如果修改变量c的值,那么会在内存中新开辟一块内存来存储这个变量,这块新的内存地址将会赋值给c。

a = 1
c = 1
c = 2
print("a:%d  c:%d" % (a,c))
print(id(a))
print(id(c))
结果:
a:1  c:2
1711072032

基本数据类型作为函数参数

基本数据类型作为函数实参同样是这个道理。

a = 1
print(id(a))
def func(x):
  print(id(x))
  x = 2
  print(id(x))

func(a)
结果:
1711072016

列表、字典等高级数据类型的引用

列表字典等高级数据类型的变量名同样存储的变量的实际地址,一个列表名赋值给另一个变量,那么这两个变量便指向内存中的同一块地址。

list1 = [1,2,3]
list2 = list1
print(list1,list2)
print(id(list1),id(list2))
结果:
[1,3] [1,3]
57931896

高级数据类型在每集加载进内存的时候内存地址与上一次可能会不同。

此时如果修改list2,也会影响list1的值,但是两个变量在内存中的地址还是不变的。这一点是与基本数据类型不一样的。

list1 = [1,id(list2))
list2.append(4)
print(list1,id(list2))

结果:
[1,3]
43841656
[1,3,4] [1,4]
43841656

此时如果有第三个列表list3的值也是[1,4],可以推测list3的地址与list1的地址应该是一样的,但是事实并非如此。如果有第三个列表list3的值也是[1,相当于在内存中新开辟一块内存来存储这个值。

list1 = [1,3]
list2 = list1
list3 = [1,3]
print(list1,list2,list3)
print(id(list1),id(list2),id(list3))
结果:
[1,3]
16775288 16776768

可变数据类型与不可变数据类型

在python中哪些是可变数据类型,哪些是不可变数据类型。可变数据类型:列表list和字典dict;不可变数据类型:整型int、浮点型float、字符串型string和元组tuple。

用一句话来概括上述过程就是:“python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


本文适合有 Python 基础的小伙伴进阶学习 作者:pwwang 一、前言 本文基于开源项目: https://github.com/pwwang/python-import-system 补充扩展讲解,希望能够让读者一文搞懂 Python 的 import 机制。 1.1 什么是 import
前言 目前有个python应用需要在容器镜像内拉取git私有仓库的代码,一开始的想法是用GitPython,折腾一番ssh私钥和known_hosts问题后,发现还是在镜像中封装个git最省事,然后用subprocess调用系统命令,镜像体积也没有想象中增加特别多。 准备ssh私钥和known_ho
前言 当网络不稳定或应用页面加载有问题,可以设置等待,避免网络问题导致找不到元素等异常。 隐式等待 隐式等待设置的是最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间结束。 隐式等待在driver的整个生命周期都有效,初始化的时候设置一次即可。 # 隐式等待10秒 drive
前言 map()、reduce()、filter()是python的三个高阶函数。所谓高阶函数,指的是将函数作为参数并返回函数作为结果的函数。下面代码的sing_ready只是一个简单高阶函数示例: def ready(name): return f"ready,{name}!"
入门使用 # 示例代码 warframe = ["saryn", "wisp", "volt"] counts = [len(n) for n in warframe] for i,j in zip(warframe,counts): pr
前言 功能描述:批量重命名指定目录下的文件,文件名加前缀,默认格式为“目录名_原文件名”。 示例代码 import argparse import os import sys import logging def gen_args(): """ 说明 解析命令行参数 &
前言 常见的应用配置方式有环境变量和配置文件,对于微服务应用,还会从配置中心加载配置,比如nacos、etcd等,有的应用还会把部分配置写在数据库中。此处主要记录从环境变量、.env文件、.ini文件、.yaml文件、.toml文件、.json文件读取配置。 ini文件 ini文件格式一般如下: [
前言 在设计API返回内容时,通常需要与前端约定好API返回响应体内容的格式。这样方便前端进行数据反序列化时相应的解析处理,也方便其它服务调用。不同公司有不同的响应内容规范要求,这里以常见的JSON响应体为例: { "code": 200, "data": {
前言 我们一般使用如下方式点击元素: elem = driver.find_element(...) elem.click() # 或者使用带等待条件的方式 elem = WebDriverWait(driver, 10).until(EC.xxx(...)) elem.click() 正常情况下,
前言 从环境变量和配置文件中获取配置参数,相关库: python-dotenv:第三方库,需要使用pip安装 configparser:标准库 示例代码 test.ini [mysql] host = "192.168.0.10" port = 3306 user = &quot
前言 Relative Locators,相对定位器,是Selenium 4引入的一个新的定位器,相对定位器根据源点元素去定位相对位置的其它元素。 相对定位方法其实是基于JavaScript的 getBoundingClientRect() 而实现,简单的页面还行,复杂页面中可能会定位到需要相同类型
简介 The pytest framework makes it easy to write small, readable tests, and can scale to support complex functional testing for applications and librari
简介 Faker库可用于随机生成测试用的虚假数据。 可生成的数据参考底部的参考链接。 安装: python -m pip install faker 快速入门 from faker import Faker # 实例化一个对象,本地化使用中国 fk - Faker(locale="zh_C
前言 原本应用的日志是全部输出到os的stdout,也就是控制台输出。因其它团队要求也要保留日志文件,便于他们用其他工具统一采集,另一方面还要保留控制台输出,便于出问题的时候自己直接看pod日志。具体需求如下: 日志支持同时控制台输出和文件输出 控制台的输出级别可以高点,比如WARNING,个人这边
按列从多个文件中构建 假设有两个csv文件,列不相同,需要整合为一个dataframe,使用glob模块: from glob import glob import pandas as pd # glob会返回任意排序的文件名,所以需要sort排序 some_files = sorted(glob(
简介 diagrams是python的一个第三方库,用于实现使用代码绘制架构图。 安装 依赖于 Graphviz,安装diagrams之前需要先安装 Graphviz(下载压缩包后,将bin目录添加到系统环境变量Path里即可)。 python3 -m pip install diagrams 快速
前言 最近有个个人需求是要把多个图片文件合并为一个PDF文件,这样方便用PDF阅读器连续看,避免界面点一下,只会图片放大。(比如看漫画) 主要思路是先把单张图片转换成单个PDF文件,然后把PDF文件进行合并。原先是用WPS的转换工具做的,但WPS每次只能批量转换30张,如果有大量图片文件,用WPS就
前言 版本: python:3.9 selenium:4.1.5 获取元素文本 text = driver.find_element(by=By.XPATH, value="").text 获取元素属性值 attr1 = driver.find_element(by=By.XPA
Python中有个内置的函数叫做 enumerate,可以在迭代时返回元素的索引。 # 示例代码01 warframe = ["saryn", "wisp", "volt"] for i,name in enumerate(warframe
前言 版本: python:3.9 selenium:4.1.5 浏览器:firefox 创建浏览器对象 from selenium import webdriver driver = webdriver.Firefox(executable_path=r"C:\software\sele