Python中,变量可以被理解为指向内存中某个对象的标签或名字。类型的“可变性”决定了当你试图改变这个对象的内容时,会发生什么?
在大多数编程语言中,值的传递通常可以分为两种形式“值传递与引用传递”,但是在Python中变量的传递基本上都是引用传递。
第一步:首先在计算机内存中创建一个数值10(占用一块内存空间)
第二步:在栈空间中声明一个变量,如a
第三步:把数值10的内存地址赋予给变量小a,形成所谓的“引用关系”
可以使用内置方法id(),其参数就是要显示的变量信息 => id(变量名称)
a = 10b = aprint(id(a))print(id(b))
说明:由以上运行结果可知,当我们把一个变量赋予给另外一个变量时,其两者指向的内存地址相同。就说明a和b指向了同一块内存空间,原理图如下:
思考:如果在b = a以后,我们改变了变量a的值,问变量b是否会受到影响?
a = 10print(id(a))a = 10b = aa = 100print(b) # 10 或 100print(id(a))print(id(b))
原理图:
总结:不可变数据类型(数值)在赋值以后,其中一个值的改变不影响另外一个变量,因为两者指向空间地址不同。
答:7种。
数值(int整型、float浮点类型)、
bool类型(True和False)、
字符串类型(str)、
元组(tuple 1,2,3)、
列表(list [1, 2, 3])、
字典(dict {key:value})、
集合(set {1, 2})
在Python中,变量可以被理解为指向实际数据对象的标签。当你执行 a = 10时,并不是把10这个值“装进”一个叫a的盒子里,而是创建了一个整数对象10,然后让变量a指向(引用)它。
根据对象创建后其值能否被修改,数据类型分为两大类:
列表(list)、字典(dict)、集合(set)
整数(int)、浮点数(float)、字符串(str)、元组(tuple)
问题2:如何判断一个数据类型是可变类型还是非可变类型?
在Python中,可变类型与非可变类型主要是通过这个数据类型在内存中的表现形式来进行定义的。
# 1. 可变类型的例子:列表 (list)print("=== 可变类型:列表 ===")list_a = [1, 2, 3]print(f"修改前,list_a 的值: {list_a}")print(f"修改前,list_a 的内存地址: {id(list_a)}")# 修改列表(原地操作)list_a.append(4) # 在末尾添加一个元素print(f"修改后,list_a 的值: {list_a}")print(f"修改后,list_a 的内存地址: {id(list_a)}") # 地址不变print("\n" + "="*30 + "\n")# 2. 不可变类型的例子:整数 (int)print("=== 不可变类型:整数 ===")int_a = 10print(f"修改前,int_a 的值: {int_a}")print(f"修改前,int_a 的内存地址: {id(int_a)}")# “修改”整数(实际上是重新赋值)int_a = int_a + 5print(f"修改后,int_a 的值: {int_a}")print(f"修改后,int_a 的内存地址: {id(int_a)}") # 地址改变!创建了新对象
# 定义一个函数def func(names): # 在函数内部更改可变变量names names.append('赵六') print(names)# 定义一个全局变量list1 = ['张三', '李四', '王五']# 调用函数func(list1)# 在全局作用域中打印list1print(list1)
原理图:
综上所述:可变类型在函数中,如果在全局或局部中对可变类型进行增删改操作,其外部和内部都会受到影响
# 定义一个函数def func(num): num += 1 print(num)# 定义一个全局变量a = 10# 调用函数func(a)# 在全局作用域中打印aprint(a)
原理图:
综上所述:不可变类型在函数中,局部或全局的改变对外部和内部都没有任何影响。
今日学习完毕,课后作业:
(1)有一段代码,定义了几种不同数据类型的变量,并对它们进行了修改;
(2)请先预测代码的输出结果,写在# 预测输出:的注释后面;
(3)然后,在编程环境中实际运行这段代码,将实际运行结果写在# 实际输出:的注释后面;
(4)最后,根据实际运行结果,简单解释为什么会出现这样的情况。