第25天:作用域——局部变量、全局变量、global

0 阅读3分钟
  • 学习目标

    • 理解局部变量:在函数内部定义的变量,只能在函数内访问
    • 理解全局变量:在函数外部定义的变量,可以在函数内读取(但不能直接修改)
    • 使用 global 关键字在函数内修改全局变量
    • 了解作用域查找规则:LEGB(Local, Enclosing, Global, Built-in)
  • 实践任务

    1. 定义一个全局变量 count = 0,编写函数 increment() 尝试修改它(观察错误),然后使用 global 修正。
    2. 编写函数 outer(),内部定义变量,再定义内部函数 inner() 尝试访问外部变量(了解闭包基础)。
    3. 分析一段代码,预测输出,然后运行验证(比如混用同名全局和局部变量)。
  • 挑战任务
    编写一个简单的计数器函数,每次调用返回递增的数字(使用全局变量或闭包)。


局部变量

在函数内部定义的变量,只在函数内部有效。函数执行结束后,局部变量会被销毁。

嵌套作用域

在函数嵌套中,内层函数可以访问外层函数定义的变量

全局变量

在模块顶层定义的变量在整个.py文件中都可以访问。

global关键字

用于在函数内部修改全局变量。

count=0
def func():
    global count
    count+=1
func()
print(count)

nonlocal关键字

用于在嵌套函数中修改外层函数的变量

count=0
def func():
    def fan():
        nonlocal count
        count=20
    fan()
    print(count)
func()

作用域查找规则

查找顺序

local:局部作用域——Enclosing:必报函数的外层作用域——Global:全局作用域——Built—in:内置作用域 python查找变量名时,会像侦探一样从内向外逐层查找。这种查找是单向的

使用建议

  1. 不在内部作用域使用与外部相同的重要变量名
  2. 使用global与nonlocal需要明确意图,避免意外创建局部变量
  3. 变量应定义在最小必要的作用域当中
  4. 合理使用嵌套作用域创建闭包,实现状态保持

实践任务

定义一个全局变量 count = 0,编写函数 increment() 尝试修改它(观察错误),然后使用 global 修正。

直接在函数内部对count进行修改时,虽然不会报错,但是会提示外部作用域被隐藏,也就是当内部使用了一个与外部变量相同的变量名时会隐藏外部的变量,修改后外部变量依旧不变 image.png 若想修改外部变量使用global就行

count=0
def increment():
    global count
    count=2
    print(count)
increment()
print(count)

image.png

编写函数 outer(),内部定义变量,再定义内部函数 inner() 尝试访问外部变量(了解闭包基础)。

def outer():
    num=12
    def inner():
        nonlocal num
        num+=1
        print(num)
    inner()
outer()

闭包是一个函数与其相关引用的组合,他可以记住并访问他被创建时的作用域中的变量,即使这个函数在其原始作用域之外执行。 image.png

分析一段代码,预测输出,然后运行验证(比如混用同名全局和局部变量)。

count=0
def increment():
    count=2
    print(count)
increment()
print(count)

image.png

挑战任务

编写一个简单的计数器函数,每次调用返回递增的数字(使用全局变量或闭包)。

def jishuqi():
    count = 0
    def num_count():
        nonlocal count
        count+=1
        return count
    return num_count

cs=jishuqi()
print(cs())
print(cs())
print(cs())

image.png