python-变量作用域

变量作用域

局部变量

python不要求声明变量,但是在函数体内赋值的变量,都会被当作局部变量。

name = 'global'
def fun():
    name = 'fun'
    print(name)

fun() #fun

 

但是如果我把赋值语句写在print语句之后呢?

name = 'global'
def fun():
    print(name)
    name = 'fun'

fun()
#UnboundLocalError: local variable 'name' referenced before assignment

为什么会报错呢?

其实在python编译函数fun的时,已经把函数体内的name当作局部变量,

但是在执行函数体内的打印语句执行时,name此时还未被赋值,所以报错UnboundLocalError。

对于这样的情况,我们最好将函数的局部变量赋值放在第一次使用它的前面。

 

global

当然,在函数体内我们也可以直接访问全局变量name

name = 'global'
def fun():
    print(name)

fun() #global

 

但是,如果我们想在函数内更改全局变量的值,该怎么办呢?

我们可以使用global声明函数内的变量为全局变量

name = 'global'
def fun():
    global name
    name = 'fun'
    print(name)

fun() #fun
print(name) #fun

 

闭包

闭包是函数和它能够访问的函数体外的变量(自由变量)组成的一个记录。

自由变量,指未在当前作用域绑定的变量。

def make_averager():
    series = []
    
    def averager(new_value):
        series.append(new_value)
        total_value = sum(series)
        total_count = len(series)
        return total_value / total_count

    return averager

avg = make_averager()
print(avg(3)) #3.0
print(avg(5)) #4.0

 

说明:当调用函数make_averager时,会产生一个闭包,这个闭包不仅包含函数averager,而且还包含自由变量series

即使定义作用域不可用了,但是闭包仍然保存对其自由变量的绑定

 

nonlocal

但是这种做法效率并不高,因为我们每次都要对自由变量求和、计算series中元素的个数,

其实我们只需存储目前的总值和元素个数即可,如下

def make_averager():
    total_value = 0
    total_count = 0
    
    def averager(new_value):
        total_value += new_value
        total_count += 1
        return total_value / total_count

    return averager

avg = make_averager()
print(avg(3))

 

但是代码会报错:UnboundLocalError: local variable 'total_value' referenced before assignmen

这是为什么呢?

total_value += new_value等价于total_value = total_value + new_value,这也就是说python编译器把total_value当作函数体内的局部变量。

对于数字、字符串、元组等不可变类型来说,只能读取,不能更改,如果尝试重新绑定,如total_value = total_value + new_value,会隐式的创建局部变量total_value,

这样total_value绑定的就不是自由变量total_value了,因此不会保存在闭包中。

 

那我们有方法使python把函数内部的变量total_value当作自由变量吗?

当然有,我们可以使用nonlocal,它的作用就是把变量标识为自由变量

def make_averager():
    total_count = 0
    total_value = 0
    
    def averager(new_value):
        nonlocal total_value, total_count
        total_value += new_value
        total_count += 1
        return total_value / total_count

    return averager

avg = make_averager()
print(avg(3)) #3.0
print(avg(5)) #4.0

 

参考资料:《流畅的python》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值