- images
- results
- .gitignore
- 1.1概论.ipynb
- 1.2 环境配置.pdf
- 1.3数据类型.ipynb
- 1.4 人机交互.ipynb
- 1.5 对象与变量.ipynb
- 1.6 编码与命名规范.ipynb
- 2.1 数值类型.ipynb
- 2.2 数值类型转换.ipynb
- 2.3 数值元算.ipynb
- 2.4常用数学运算函数.ipynb
- 2.5 math 模块及其应用.ipynb
- 2.6.1 逻辑值测试.ipynb
- 2.6.2 成员运算.ipynb
- 2.6.3 比较运算.ipynb
- 2.6.4 布尔运算.ipynb
- 2.6.5 运算优先级.ipynb
- 2.ipynb
- 3.1 流程控制结构.ipynb
- 3.3.1 for 循环语句.ipynb
- 3.3.3 rang.ipynb
- 3.3.3 while 循环语句.ipynb
- 3.4 and 3.5 分支结构和条件.ipynb
- 3.6 and 3.7 .ipynb
- 3.9 异常处理.ipynb
- 4 函数和模块化编程.ipynb
- 4.1 函数的定义、调用与返回值.ipynb
- 4.2 函数的参数传递.ipynb
- 4.3 变量的作用域.ipynb
- 4.4 匿名函数.ipynb
- 4.5 递归.ipynb
- 4.6 内置函数.ipynb
- 4.7 模块化程序设计.ipynb
- 5.1 序列通用操作.ipynb
- 5.1.1 索引.ipynb
- 5.1.2 切片.ipynb
- 5.1.3 序列拼接与重复.ipynb
- 5.1.4 成员测试.ipynb
- 5.2.1 字符串的创建.ipynb
- 5.2.2 字符串常量.ipynb
- 5.2.4 字符串的遍历.ipynb
- 5.2.5 文件遍历.ipynb
- 5.2.6 字符串的处理方法.ipynb
- 5.2.7 字符串格式化.ipynb
- 5.2.8 转义字符.ipynb
- 5.3 random 模块及其应用.ipynb
- 6.1 元组.ipynb
- 6.2 列表.ipynb
- 6.2.1 列表的创建.ipynb
- 6.2.2 列表的更新.ipynb
- 6.2.3 列表的删除.ipynb
- 6.2.4 列表的排序.ipynb
- 6.2.5 列表赋值与复制.ipynb
- 6.2.6 列表推导式.ipynb
- 6.2.8 常用内置函数.ipynb
- 6.2.9 列表嵌套及其排序.ipynb
- 6.3 列表综合应用.ipynb
- 7.1.1 集合的创建.ipynb
- 7.1.2可变集合类型的操作.ipynb
- 7.1.3 成员关系.ipynb
- 7.1.4 集合关系.ipynb
- 7.1.5 集合运算.ipynb
- 7.2.1 字典创建.ipynb
- 7.2.2 获取字典值.ipynb
- 7.2.3 修改字典值.ipynb
- 7.2.4内置函数与方法.ipynb
- 7.2.5字典排序输出.ipynb
- 7.3 集合与字典的应用.ipynb
- 8 中 numpy 概述.ipynb
- 8 中panda 库.ipynb
- 8.1 文件的打开与关闭.ipynb
- 8.2 文件读写操作.ipynb
- 8.3 文件的应用.ipynb
- 8.4 numpy 文件操作.ipynb
- 8.4.2 and 3.ipynb
- 8.5.1 pandas文件读写.ipynb
- 8.5.2 and 3 and 4.ipynb
- 9.1 matplotlib 线性图.ipynb
- 9.1.5 数据文化绘图.ipynb
- 9.2 非线性图.ipynb
- 9.3 词云.ipynb
- _overview.md
- _readme.ipynb
- coding_here.ipynb
- dream.png
- score.txt
- score_total.csv
- 成绩分析综合.json
4.3 变量的作用域.ipynb @master — view markup · raw · history · blame
4.4 变量作用域¶
变量的作用域就是指__变量的有效范围__,变量按照作用范围分为两类:__全局变量__和__局部变量__。</font>
在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空间中进行,我们称之为__命名空间__,也被称之为__作用域__。</font>
Python的作用域是__静态的__。</font>
在源代码中__变量名被赋值的位置__决定了该变量能被访问的范围,即Python变量的__作用域__由变量所在源代码中的__位置__决定。</font>
在Python中,并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。
本节我们只讨论与函数相关的变量作用域。
可以简单的说,在__函数外部__声明的变量是__全局变量__,其作用域是__整个文件(或模块)__;在__函数内部__声明的变量是__局部变量__,其作用域是声明这个变量的__函数内部__,在__函数外部不可以访问__。</font>
4.4.1 局部变量¶
__局部变量是__在函数中定义的变量,包含在def关键字定义的语句块中。
__函数每次被调用时都会创建一个新的对象__。因此,局部变量仅仅是__暂时的__存在,依赖创建该变量的函数是否处于活动状态。函数调用时创建,函数调用结束后销毁并释放该变量的内存。
def myName():
general_name = '赵云' # 函数内部定义的局部变量
print(general_name) # 输出赵云
myName() # 调用函数myName(),打印 赵云
print(general_name) # general_name,NameError: name 'general_name' is not defined
general_name变量是在myName()函数内部定义的,属于局部变量,只能在函数内部访问,在函数外部访问时会返回__NameError__异常。
4.4.2 全局变量¶
__全局变量是__在模块(文件)层次中定义的变量,每一个模块都是一个__全局作用域__。也就是说,在模块文件__顶层__声明的变量都是全局变量,其__作用域是当前模块文件内__,从变量定义处开始直到文件末尾都是其有效范围,包括__函数外部和函数内部__。
注意,上一句话里的“顶层”是一个逻辑概念,指函数之外、和函数定义处于同一层次,并不是一个位置概念(即文件开始处)。
全局变量在模块文件运行的过程中会__一直存在__,占用内存空间,一般建议尽量少定义全局变量。
def myName():
print(general_name) # 函数内部访问全局变量general_name,打印其值 赵云
general_name = '赵云' # 定义全局变量general_name
myName() # 调用函数myName()
print(general_name) # 函数外部访问全局变量general_name,打印其值 赵云
函数内部__可以__直接访问和引用全局变量的值,但__不能直接改变__全局变量的值。在函数内部,全局变量应该出现__在赋值符号的右边__,一旦全局变量出现在赋值符号的__左边__,系统会认为这是__重新创建__了一个__同名的局部变量对象__。其值变为在函数体内重赋的新值,同时__屏蔽__外层作用域中的同名变量。
def myName():
general_name = '张飞' #函数内定义局部变量,会屏蔽掉同名的全局变量
print("局部变量的内存地址:{}".format(id(general_name)))
print("局部变量general_name的值:{}".format(general_name)) # 输出局部变量name的值 张飞
general_name = '赵云' #函数外定义的全局变量
print("全局变量的内存地址:{}".format(id(general_name)))
myName() # 调用函数myName()
print("全局变量general_name的值:{}".format(general_name)) # 输出全局变量name的值 赵云
在这个例子里,general_name 本是一个全局变量,myName()函数中被放到了赋值符号左侧重新赋值,这个操作相当于重新创建了一个新的对象“张飞”,并为这个对象贴上一个标签“general_name”。虽然两个对象的名称一样,但分配的内存地址不同,所以是不同的两个对象。因为这个对象和标签都是在函数内部创建的,所以是一个__新的局部变量__,其作用域是这个函数体。
也就是说,__在函数体内__访问general_name,__访问的是局部变量__,其值是“张飞”;__在函数体外__访问变量general_name时__访问的是全局变量__,其值是“赵云”。
这个规则适用于所有全局变量值为__固定数据类型__的情况,如全局变量值为数字型、字符型和元组等。此时,函数体内试图改变全局变量值时,都会创建一个新的局部变量。
在函数内部的变量声明,除非__特别声明为全局变量__,否则均默认为局部变量。 当需要在函数体内声明一个可以在函数体外访问的全局变量的值时,可以使用__global关键字__来声明变量的作用域为全局。global的作用就是把局部变量提升为全局变量。
def myName():
global general_name # 声明一个全局变量general_name
general_name = '张飞' # 为全局变量general_name赋值
print("新全局变量general_name的内存地址:{}".format(id(general_name)))
print("新全局变量general_name的值:{}".format(general_name)) #输出局部变量general_name值‘张飞’
general_name = '赵云'
print("原全局变量name的内存地址:{}".format(id(general_name)))
print("原全局变量name的值:{}".format(general_name)) # 输出全局变量general_name的值‘赵云’
myName() # 调用函数myName()
print("general_name的值:{}".format(general_name)) # 输出全局变量general_name的值‘张飞’
print("general_name的内存地址:{}".format(id(general_name)))
从输出结果可以发现,在myName()函数调用后,__函数外再次访问全局变量__general_name时,访问的是最近在函数内部声明的全局变量。
__当全局变量值为列表等可变数据类型__时,如果__函数内部需要修改全局列表变量的值__时,__不需要使用global关键字__进行声明,直接可以使用。这是因为列表等可变数据类型的值的修改是在原内存进行的,只有显式声明才会重新创建对象。
def myName():
lsx.append(1) #改变全局变量lsx的值,未重新创建对象
lsy = [2,3,4] #重新创建了对象,此时lsy为局部变量
print(id(lsx),id(lsy)) #打印内存地址
print(lsx,lsy) # lsx 的值为[1] ,lsy 的值为[2, 3, 4]
lsx = [] #lsx为全局变量
lsy = [] #lsy为全局变量
print(id(lsx),id(lsy)) # 打印内存地址
myName() # 调用函数myName()
print(lsx,lsy) # lsx的值变为[1],lsy值仍为 [],未发生变化
可以发现,__函数内外lsx的id值相同__,说明二者是相同的对象,函数内只是修改了lsx并__未重新创建对象__。
而__函数内外lsy的id值不同__,说明二者是不同的对象,函数内部lsy = [2,3,4]这条语句__重新创建对象__[2,3,4],并赋值给变量lsy。