01.变量的引用
- 变量 和 数据 都是保存在内存中的。
- 在Python中,函数的参数传递以及返回值都是靠引用传递的。
1.1 引用的概念
在python中
- 变量 和 数据 是分开存储的
- 数据 保存在内存中的一个位置
- 变量 中保存着数据在内存中的地址
- 变量 中 记录数据的地址,就叫做引用
- 使用id()函数可以查看变量中保存数据所在的 地址内存
如图:
注意:如图可见,如果变量已经被定义,当给一个变量赋值的时候,本质上是修改了数据的引用。变量不再对之前的数据引用,改为对新赋值数据的引用。
1.2 变量引用的示例
在Python中,变量的名字类似于便签纸贴在数据上。
- 定义一个整数变量a,并赋值为1。
- 将变量a赋值为2。
- 定义一个整数变量b,并把a的值赋值给b。
1.3 函数中的参数和返回值的传递
由图中代码运行结果可知,在Python中,调用函数的时候,本质上传递的是实参保存数据的引用,而不是实参保存的数据。返回数值的时候,返回的也是数据的引用,而不是数据本身。
即函数的实参/返回值都是靠引用来传递的。
02. 可变和不可变类型
- 不可变类型,内存中的数据不允许被修改
- 数字类型 int、bool、float、complex、long(2,x)
- 字符串 str
- 元组 tuple - 可变类型,内存中的数据可以被修改
- 列表 list
- 字典 dict
注意:
- 可变类型的数据变化,只能通过 方法 来实现。
- 如果给一个可变类型的变量,引用会修改
- 变量 不再 对之前的数据引用
- 变量 改为 对新赋值的数据的引用
对列表的操作:
①使用方法
②重新赋值
对字典的操作
①使用方法
注意:字典的key只能使用不可变类型的数据
②重新赋值
03. 局部变量和全局变量
- 局部变量 是在 函数内部定义的变量,只能在函数内部使用
- 全局变量 是在 函数外部定义的变量(没有定义在某一个函数内),所有函数内部都可以使用这个变量
3.1 局部变量
- 局部变量 是在 函数内部 定义的变量,只能在函数内部使用
- 函数执行后,函数内部的局部变量,会被系统回收
- 不同的函数,可以定义相同的局部变量,但是各自使用各自的,不会产生影响
局部变量的作用
- 在函数内部使用,临时 保存 函数内部需要使用的数据
如图,局部变量只能在函数内部调用。
局部变量的生命周期
- 所谓生命周期就是变量从被创建到被系统回收的过程
- 局部变量在函数执行的时候才会被创建
- 局函数执行结束后局部变量被系统回收
- 局部变量在生命周期内,可以用来存储函数内部临时使用到的数据
利用Pycharm调试工具可以清晰的看到,num变量只有在使用的时候才会被创建,函数调用完成后,会被系统回收:
第一步: 准备调用函数
第二步: 进入函数
第三步:执行完num行代码后, 创建num
第四步: 函数执行完成后,变量num死亡
不同变量中同名变量互不影响
如图,在不同函数中,同名变量的使用互不影响。
3.2 全局变量
- 全局变量是在函数外部定义的变量,所有函数内部都可以使用这个变量
如图,全局变量在所有位置都可以使用。在函数内部调用全局变量的时候,会首先寻找局部变量比对,如果没有的话,再寻找全局变量。
在Pycharm中,可以利用单步执行,清晰的观察到在demo2()输出函数前,num被局部变量赋值为20输出。
注意:
- 在python中,函数内部可以通过全局变量的引用获取对应的数据
- 但是,不允许直接修改全局变量的引用——即使用赋值语句修改全局变量的值
如在下图中,demo2()中的num修改并未修改全局变量的值,只是相当于在demo2()中定义了局部变量num。
在函数中修改全局变量的值
- 如果想在函数中修改全局变量,需要使用global进行声明,告诉python解释器,某变量为全局变量。
如图,在demo2()函数中,首先使用global告诉pycharm编译器,num为全局变量,再进行修改后,即对全局变量的值进行的修改。而此时,不会在demo2()中创建局部变量了。
注意:
我们在使用全局变量的时候,要在函数调用前,定义好函数内部所需要的全局变量。
最好在开发时,把模块中所有的全局变量,定义在所有函数上方,可以保证所有函数都能正常访问每一个全局变量。
如下图,我们在函数调用前定义title_01、title_02,在函数内部可以正常使用,可是在函数调用后定义title_03,虽然在代码书写上没有错误,可是在执行后会报错。
如何给全局变量命名?
- 为了避免局部变量和全局变量出现混淆,在定义全局变量的时候,有些公司会有一些开发要求,比如:
- 全局变量名前应该增加g_或者gl_的前缀
- 具体情况具体分析