首页 > 编程语言 >Python中的变量

Python中的变量

时间:2023-10-04 20:15:48浏览次数:50  
标签:变量 Python list1 list2 内存地址 id

Python中的变量


变量的定义

程序中,数据临时存储在内存中。
每一个被存储在内存的数据都有一个内存地址
其中特定的数据被我们所使用,因此我们为那些内存地址定义了名称。
这一名称被称作 标识符,又称变量名
而与变量名对应内存地址中的数据被称为变量值

总结:变量为内存中特定的数据。它的内存地址的名称为变量名,它的值为变量值

在Python中,查看变量内存地址的方式为:id()
如:

>>>a = 1
>>>id(a)
140718160995112

变量的赋值方法

赋值:定义变量。

在Python里用等号=来给变量赋值。
如:

>>>name = '总之先找时光机!'
>>>name
'总之先找时光机!'
>>>id(name)
2742705886128

其中name为变量名,'总之先找时光机!'是变量值。这个数据被存储在地址:2742705886128中。


变量名的命名规范

标识符(又称变量名)命名规则是Python中定义各种名字的时候的统⼀规范,具体如下:

规则

  • 由数字、字母、下划线组成

注意

  • 不能用数字开头或只用数字
  • 不能用Python内置的关键字或类型
  • Python区分变量名大小写
>>>import keyword
>>>print(keyword.kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

除了基础的规则之外,还有其他约定俗称的命名法。不过不同的单位与公司都有自己的编程规范,在此只介绍最基础的四种命名法:驼峰命名法、帕斯卡命名法、下划线命名法、匈牙利命名法。

驼峰命名法

又称小驼峰式命名法。该命名规范,要求第一个单词首字母小写,后面其他单词首字母大写。
如:

>>>myName = '总之先找时光机!'

帕斯卡命名法

又称大驼峰式命名法。该命名规范,每个单词的第一个字母都要大写。
如:

>>>MyName = '总之先找时光机!'

下划线命名法

该命名规范,要求单词与单词之间通过下划线连接即可。
如:

>>>my_name = '总之先找时光机!'

匈牙利命名法

该命名规范,要求前缀字母用变量类型的缩写,其余部分用变量的英文或英文的缩写,单词第一个字母大写。
如:

>>>sMyName = '总之先找时光机!'    # 这一变量为 str 类型

考虑到Python内的类型转换比较自由,不建议使用该命名法。


变量的数据类型介绍

在Python里,数据的类型如下:

查看数据类型的方法:type()
如:

>>>a = 1
>>>type(a)
<class 'int'>

>>>b = 1.1
>>>type(b)
<class 'float'>

>>>c = True
>>>type(c)
<class 'bool'>

>>>d = '12345'
>>>type(d)
<class 'str'>

>>>e = [10, 20, 30]
>>>type(e)
<class 'list'>

>>>f = (10, 20, 30)
>>>type(f)
<class 'tuple'>

>>>h = {10, 20, 30}
>>>type(h)
<class 'set'>

>>>g = {'name': 'TOM', 'age': 20}
>>>type(g)
<class 'dict'>

Python中的复杂赋值与深浅拷贝

参考内容:Python中的赋值(复制)、浅拷贝与深拷贝

不可变类型

在Python中首先定义一个变量a = 1

>>>a = 1
>>>id(a)
140718136222504

此时一个数值1被存储在了内存空间,它所存储的内存地址为140718136222504。对应该地址的标识符(变量名)为a
如果再创建一个变量b = a,会发生什么呢?

>>>a = 1
>>>id(a)
140718136222504
>>>b = a
>>>id(b)
140718136222504
>>>b
1

使用id(b)查验该标识符对应的内存地址即可发现:标识符a和标识符b对应的是同一个内存地址。
这意味这Python并没有重复在内存空间内存储数值1,只是将标识符b与存储数值1的内存地址对应起来而已。
也就是说,现在内存地址140718136222504现在有两个名称,一个是标识符a,另一个是标识符b

当我们对变量ab分别进行操作并改变它们的变量值时,他们的存储地址和变量值又会发生什么改变呢?

>>>a = 1
>>>b = a
>>>id(a)
140718136222504
>>>id(b)
140718136222504
>>>a = a + 1
>>>a
2
>>>id(a)
140718136222536
>>>b = b - 1
>>>b
0
>>>id(b)
140718136222472

在我们对变量a和变量b进行加减操作后,存储变量ab的内存地址改变了,而不是内存地址内的值改变了。

如果我们查验数值0,1,2的存储地址,就会发现它们与变量值为0,1,2的变量享有同样的存储地址:

>>>id(0)
140718136222472
>>>id(1)
140718136222504
>>>id(2)
140718136222536

对于这类改变变量值会改变内存地址的变量类型,我们称为不可变类型
所有数值类型、序列类型中的字符串和元组都属于不可变类型。它们的内存地址随着值的变化而变化

可变类型

与不可变类型相对的,就是可变类型。包括列表、集合与字典。
可变类型变量的内存地址不会随着值的变化而改变

现在先定义一个可变类型变量list1 = [1, 2, 3, 4]

>>>list1 = [1, 2, 3, 4]		# 这里以list举例
>>>id(list1)
2185105682944
>>>list1[3] = 5
>>>list1
[1, 2, 3, 5]
>>>id(list1)
2185105682944

可以发现当我改变了list1内的元素,变量的内存地址并未发生改变。

现在再创建一个list2 = list1,并再次尝试改变变量list2的值。

>>>list2 = list1
>>>id(list1)
2185105682944
>>>id(list2)
2185105682944
>>>list2[0] = 6		# 改变list2中第0元素的值
>>>list1			# list1也发生改变了
[6, 2, 3, 5]
>>>list2
[6, 2, 3, 5]

在我们创建list2 = list1后,再查验变量list1list2的内存地址,发现它们是一样的。
并且当我们改变变量list2的内容,变量list1的内容也改变了。
原因很简单,因为标识符list1list2指向的是同一个内存地址:我们通过标识符list2去改变内存地址内的数据后,用标识符list1查验了同一个内存地址内的数据。

copy module

偶尔,我们希望保留部分或者全部原始数据。Python中的copy标准库提供了解决方案。

copy标准库的交互

copy.copy(x)
Return a shallow copy of x. 返回一个浅拷贝。

copy.deepcopy(x)
Return a deep copy of x. 返回一个深拷贝。

深浅拷贝的区别

当拷贝的对象是复合对象(即对象中包含其他对象,如列表中包含另一个列表)时:

  • 浅拷贝创建一个新的复合对象,但内部的可变类型的内存地址被继承。
  • 深拷贝创建一个新的复合对象,且内部的可变累型也会被递归拷贝。
>>>import copy
>>>list1 = [1, [2, 3], 4, 5]
>>>list2 = copy.copy(list1)
>>>list3 = copy.deepcopy(list1)
>>>id(list1)
1754106448256
>>>id(list2)
1754106449216
>>>id(list3)
1754103446080

上述代码创建了三个变量。
其中list1[1]为嵌套的list类型。
list2list1的浅拷贝,list3list1的深拷贝。
此时标识符list1list2list3各自对应不同的内存地址。

因为三个变量拥有不同的内存地址,所以我们直接对单个变量进行操作,这样的改变不会影响其他变量。
如:

>>>list1
[1, [2, 3], 4, 5]
>>>list2
[1, [2, 3], 4, 5]
>>>list3
[1, [2, 3], 4, 5]
>>>list1.append(6)
>>>list2.append(7)
>>>list3.append(8)
>>>list1
[1, [2, 3], 4, 5, 6]
>>>list2
[1, [2, 3], 4, 5, 7]
>>>list3
[1, [2, 3], 4, 5, 8]

但如果我们检查各个变量内嵌套的可变类型元素的内存地址,就会发现深浅层拷贝的区别:

id(list1[1])
1754106220480
id(list2[1])
1754106220480
id(list3[1])
1754106448960

我们发现,浅拷贝(list2)中嵌套的list元素与正本(list1)中的它享有同样的内存地址,而深拷贝(list3)中的它则拥有不同的内存地址。
因此,如果我们对浅拷贝副本中的可变类型元素做出改变,我们期待正本中的可变类型元素也会对应地发生改变,因为它们拥有同样的内存地址。

>>>list2[1].append(9)
>>>list1
[1, [2, 3, 9], 4, 5, 6]
>>>list2
[1, [2, 3, 9], 4, 5, 7]
>>>list3
[1, [2, 3], 4, 5, 8]

标签:变量,Python,list1,list2,内存地址,id
From: https://www.cnblogs.com/wanderoff-night/p/17742639.html

相关文章

  • python_day3
    Python_day31、列表index=0whileindex<len(列表): 元素=列表[index]对元素进行处理index+=1方法2:for临时变量in数据容器: 对临时变量进行处理while循环可以控制循环条件,但是for循环不行2、元组元组一旦被定义就不能被修改元组:使用小括号,且使......
  • 笨办法学Python3 习题20 函数和文件
    脚本函数运行内容:系统模块导入参数变量解包参数变量(脚本,文件变量1)定义函数1,执行读取文件定义函数2,执行读取位置移动到文本开头定义函数3(参数1,参数2),执行打印参数1,读取参数2的一行打开文件变量1赋值刚创的文档变量调用函数1,读取文件调用函数2,读取位置移动到文本开头......
  • 笨办法学Python3 习题19 函数和变量
    定义调用函数:全局变量名和函数变量名避免取相同的名字函数之外的变量不会改变函数中原来的变量,调用函数时会被临时创建,函数运行完就会被丢弃定义函数(参数变量1,参数变量2):    函数命令打印你有参数变量1的干酪    打印你有参数变量2的干酪盒子   ......
  • 笨办法学Python3 习题18 命名、变量、代码和函数
    知识点:定义函数的格式def函数名1(参数1,参数2):   函数命令def函数名2(*args):   解包   函数命令def函数名3(参数1):   函数命令def函数名4():  # 可以是无参数的函数   函数命令函数名1(参数值,参数值)#调用函数1函数名2(参数值,参数值)#......
  • python多进程:fork模式和spawn模式
    python多进程:fork模式和spawn模式fork模式1.仅unix系统支持,并且是unix系统的默认模式.2.使用该模式创建子进程的时候,会复制父进程的全部变量,支持传参(任意类型)给子进程,但是不会复制父进程的线程.3.该模式相当于将父进程的内存复制一份用于创建子进程.但是由于不复制线程......
  • 笨办法学Python3 习题17 更多文件操作
    脚本运行内容:系统模块导入参数变量导入os.path模块调用exists函数  解包参数变量(脚本,被复制文件1,粘贴到文件2)打印语句,需要复制文件1内容到文件2打开文件1读取文件1打印语句,中间用到格式化,len(X)函数来运算文件1中字符长度打印语句,中间用到格式化,exists(Y)函数......
  • 流畅的python笔记 (二) 2.序列构成的数组
    内置序列类型分类1:容器序列(能存放不同类型):list,tuple,collections.deque扁平序列(不能存放不同类型):str,bytes,bytearray,memoryview,array.array分类2:可变序列(能被修改):list,bytearray,array.array,collections.deque,memoryview不可变序列:tuple,str,bytes列表推导......
  • python练习2 | 类的继承
    点击查看代码#类继承练习:人力系统#员工分为两类,全职员工FullTimeEmployee、兼职员工PartTimeEmployee#全职和兼职都有”姓名,name,工号:id属性#都具备打印信息print_info(打印姓名、工号)方法#全职有月薪monthly_salary属性#兼职有日薪daily_salary属性,每月工作天数......
  • C++ Thread 条件变量
    Condition_Variable介绍条件变量是利用线程间共享的全局变量进行同步的一种机制条件变量是为了控制多线程有顺序地访问共享资源,它和互斥量协同控制多线程有序,互斥地访问共享资源,重要解决的问题是生产者和消费者的问题variable_condition该类是专门结合unique_lock使用......
  • Python笔记
    第一章、Python概述1.1 扩展库安装方法使用pip命令安装扩展库。在cmd命令行中输入pip,回车后可以看到pip命令的使用说明。1.2 常用的pip命令pip命令示例说明pipfreeze[>requirements.txt]列出已安装扩展库及其版本号(不知道怎么用。。?)pipinstallSomePacka......