大爽Python入门教程 6-2 变量进阶 局部变量`local`与全局变量`global`

大爽Python入门公开课教案 点击查看教程总目录

1 定义

这里来看一个例子。
不妨猜一下这个输出是多少。

def change_local(x):
    x += 1

x = 5
change_local(x)
print(x)

答案是

5

这个例子中,函数内部的改动,没有对函数外部生效。
这是因为函数内部的x和函数外面的x其实是两个。

函数外面定义的,是全局(global)变量。
函数里面定义的,是局部(local)变量。
在python中,局部变量和全局变量的定义差不多就是这样。

把上面的代码这么来写,应该就很容易看懂了

def change_local(local_x):
    local_x += 1

gloabl_x = 5
change_local(gloabl_x)
print(gloabl_x)

2 作用域

什么是作用域?
可以简单理解为,能生效的范围,
或者说能使用能调用的范围。

之前讲过,变量要先声明后调用,
在声明之前调用,会报错
NameError: name 'var' is not defined 其中var是调用的变量名

局部变量

局部变量的作用域是在函数内,
即在函数内能调用(先声明后调用),
函数外调用会报错NameError

示例如下

def create_local():
    x = 1

create_local()
print(x)

报错如下

NameError: name 'x' is not defined

全局变量

全局变量的作用域是整个程序(目前可以简单理解为整个代码文件),
即在所有位置都能调用(先声明后调用),
也包括函数里面

x = 10

def use_global():
    print(x)

use_global()

输出为

10

x的声明放在函数声明之后都是可以的,只要保证在调用之前就先行。

def use_global():
    print(x)

x = 10
use_global()

此时输出也是10

x的声明放在函数调用之后则不行,会报错,如下

def use_global():
    print(x)

use_global()
x = 10

会报错

NameError: name 'x' is not defined

优先级

函数中,有同名的全局变量和局部变量时,
优先使用局部变量。
示例如下

def use_who():
    x = 5
    print(x)

x = 10
use_who()

输出如下

5

3 修改全局变量

在函数外,修改全局变量很简单,
即正常的修改或赋值。

函数内如何修改全局变量呢,
或者说让函数内的修改在函数外生效。

函数内可以调用全局变量,但是不能直接修改,
直接修改要么不会生效,要么会报错。

不生效

x = 20

def invalid_change():
    x = 10

invalid_change()
print(x)
x = 20

def invalid_change(x):
    x = 10

invalid_change(x)
print(x)

两段代码输出都是20
这个现在大家应该能理解。

简单来讲,就是在函数内部使用的x,
其声明是在函数内部的,是局部变量,

正确方法

def change():
    global x
    x = 20

x = 10
change()
print(x)

输出如下

20

即在本来使用局部变量的函数区域内,
使用global进行全局变量声明,则此时的调用和修改是在全局上生效的。

注意: 可以认为只有这个写法。
此时不能通过函数传参x了,此时会报错SyntaxError
示例如下

def change(x):
    global x
    x = 20

x = 10

change(x)
print(x)

报错

SyntaxError: name 'x' is parameter and global

参数会和全局变量声明冲突

4 直接修改报错探究

偏难,属于探究内容

直接修改报错

那么如果不声明,直接在函数内部先调用全局变量并修改呢。

x = 20

def wrong_change():
    x += 1

wrong_change()
print(x)

其报错如下

UnboundLocalError: local variable 'x' referenced before assignment

这个错误现在看英文,比较难理解。

换个写法还报错

我们换个写法,并逐步分析。
x += 1 可以换成 x = x + 1

x = 20

def wrong_change():
    x = x + 1

wrong_change()
print(x)

此时仍然报错UnboundLocalError,和上面一样。

拆开执行不报错

那么把赋值符号两边的拆开执行看看。

x = 20

def wrong_change():
    print(x+1)

wrong_change()

这个能执行,输出为21

x = 20

def wrong_change():
    x = 20 + 1

wrong_change()

这个也可以执行,无输出(未print)

合到一起再报错

但是将这两个合到一起,就无法执行了。
即如下

x = 20

def wrong_change():
    print(x+1)
    x = 20 + 1

wrong_change()

会报错

UnboundLocalError: local variable 'x' referenced before assignment

这是为什么呢?

原因

因为函数里面这个x只能有一个意义,或者说一个身份。
它可以是全局变量(此时不是局部),也可以是局部变量(此时不是全局)。

但它不能同时都是,不能一个函数里面,
第一行的x是全局变量,第二行的x是局部变量。

再回来看报错,这种冲突情况下,
会认为x是局部变量,所以错误在于赋值之前进行调用。

5 练习实践

要求

使用全局变量实现简易计数功能

具体为在控制台中
能够输出Count num(初始值设定为10)
输入一个w, Count num增加1
输入一个s, Count num减少1
输入一个e, 退出
输入其他字符不处理。
可以一次输入多个字符串,从前往后按上面的逻辑处理

运行效果如下

COUNT NUM: 10
input: w
COUNT NUM: 11
input: w
COUNT NUM: 12
input: s
COUNT NUM: 11
input: www
COUNT NUM: 14
input: ss
COUNT NUM: 12
input: e
BYE

框架


def increase_count():
    pass


def decrease_count():
    pass


def main():
    count = 10

    while True:
        print("COUNT NUM: %s" % count)
        s = input("input: ")
        for c in s:
            # handle
            pass

main()

答案

要点说明:

  1. 如果在函数外部声明过全局变量,函数内部就可以global调用并修改。
  2. 函数内部使用了局部变量之后,不能对局部变量使用global。就是说,如果函数内部想添加全局变量,必须先声明后赋值(语句还不能合并)。
def increase_count():
    global count
    count += 1


def decrease_count():
    global count
    count -= 1


def main():
    global count
    count = 10

    while True:
        print("COUNT NUM: %s" % count)
        s = input("input: ")
        for c in s:
            if c == "w":
                increase_count()
            elif c == "s":
                decrease_count()
            elif c == "e":
                print("BYE")
                return

main()
posted @ 2021-11-29 21:49  大爽歌python编程辅导  阅读(433)  评论(1编辑  收藏  举报