Python中的全局变量和局部变量

python中的全局变量和局部变量

当你在用python封装一个函数时,遇到了下面这样的情况

# 记骰子的点数
total = 0
def roll_dice(n=2):   # 可以设计默认值为2
    for _ in range(n):
        total += randint(1,6)
    return total
result = roll_dice(6)
print(result)

初略一看,代码没什么问题,但是一运行,给你一个大大的UnboundLocalError:

UnboundLocalError: local variable ‘total’ referenced before assignment

意思是 “局部变量total在赋值前被引用

也就是说,total这个变量还没有给它赋值,我们就引用它了。那为什么会这样呢?这是因为我们在初始化total时并不是在函数体中初始化的,是在函数外定义的,这样做的结果就会让系统在函数体中执行代码时找不到total的初始值,所以它认为你没有定义过total

但有时我们并不想在函数体内定义它,就行用函数外的变量

解决方法:在函数体中的变量total前global关键字,如下:

# 记骰子的点数
total = 0
def roll_dice(n=2):   # 可以设计默认值为2
    global total      # global关键字加在这里
    for _ in range(n):
        total += randint(1,6)
    return total
result = roll_dice(6)
print(result)

这样做后就可以正常运行了。

问题倒是解决了,但是为什么要这样做呢?

如果你是来解决问题的,那你可以走了,如果是来学习的,请看完本文。

全局变量和局部变量

一般来说,在函数体外定义的变量叫全局变量,而在函数体内定义的变量叫做局部变量,C语言中也称为内部变量,而局部变量只能在这个函数内部使用,全局变量则是可以作用到整个文件(模块)的范围。

在使用局部变量和全局变量时,下面几点是需要格外注意的:

  • 1.局部变量只能在这个函数内部使用,全局变量则是可以作用到整个文件(模块)的范围

  • 2.在python程序中搜索一个变量按照LEGB顺序进行搜索的

是这样的顺序:

Local(局部作用域)———> Embeded(嵌套作用域)——>Global(全局作用域)——>Built-in(内置作用域)——>NameError :name… not defined

如:

x = 100            # 全局变量X


def foo():   
    x = 200        # 嵌套作用域的局部变量X,函数foo中又嵌套了bar函数

    def bar():
        x = 300    # 局部变量x
        print(x)    

    bar()
    print(x)


foo()        # 先思考以下输出结果是什么
print(x)     # 这里输出什么呢?

输出结果

300
200
100

也就是说,它是这样变量x是这样找的

在这里插入图片描述

那么,现在改一下,现在又输出什么呢?

x = 100            # 全局变量X


def foo():   
                   # 嵌套作用域的局部变量X,函数foo中又嵌套了bar函数

    def bar():
                   # 局部变量x
        print(x)    

    bar()
    print(x)


foo()        # 先思考以下输出结果是什么
print(x)     # 这里输出什么呢?

输出结果

100
100
100

可知,他的搜索顺序是这样的:

在这里插入图片描述

若在全局范围域还是没有找到,就看是不是python内置的变量名,若都没有找到就返回

NameError: name ‘x’ is not defined这样的异常,意思是说,x这个名字是没有被定义的

那么知道这样的搜索顺序之后,第三点是

  • 3.如过在函数体中要使用全局变量请使用关键字global,如
x = 100


def foo():
    # 如果我不想在函数foo中定义局部变量x,想直接使用全局变量x,应该怎么做???
    global x     
    x = 200        # 使用全局变量后,这里重新赋值,全局变量的值也就等于了现在的200

    def bar():
        x = 300
        print(x)

    bar()
    print(x)


foo()        # 输出300,200
print(x)     # 输出200

  • 4.不想在函数bar中定义局部变量x,想直接使用嵌套作用域中的x

这时候使用nonlocal关键字,如

x = 100


def foo():
    x = 200

    def bar():
        # 如果我不想在函数bar中定义局部变量x,想直接使用嵌套作用域中的x,应该怎么做???
        nonlocal x
        x = 300
        print(x)

    bar()
    print(x)


foo()          # 300,300
print(x)       # 100

在这里插入图片描述

好了,这下知道为什么文章开头那样会报错了吧!

如果对你有帮助,不要忘记点赞、关注、评论加收藏哦!

  • 16
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python和数据分析

钟意作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值