4. 变量的作用域

局部作用域(Local Scope)

局部作用域是指在函数内部定义的变量的作用范围。这些变量只能在函数内部访问,函数执行结束后,变量就会被销毁。

python
# 示例1
def ex1():
    n = 10
    print("函数内部,局部变量的值:", n)

ex1()
# print(n)  # 这会导致 NameError,因为 n 超出了作用域

# 示例2
def ex2(a, b):
    result = a + b
    return result

s = ex2(3, 5)
# 这里只能访问函数的返回值,无法直接访问函数内部的 result 变量
print("函数返回的结果:", s)

# 示例3
def ex3():
    x = 20
    if x > 10:
        y = x * 2
        print("条件块内,y的值:", y)
    print("函数内,x的值:", x)
    # 虽然y是在条件块内定义,但仍在函数的局部作用域内,可在此处访问
    print("函数内,y的值:", y)

ex3()
# print(y)  # 这会导致 NameError,y在函数外部不可见

▶ 运行结果:

输出
函数内部,局部变量的值: 10
函数返回的结果: 8
条件块内,y的值: 40
函数内,x的值: 20
函数内,y的值: 40

全局作用域(Global Scope)

全局作用域是指在模块(整个 .py 文件)顶层定义的变量的作用范围。全局变量在整个模块内都可以访问,除非在局部作用域中被重新定义。

python
# 示例1
n = 50

def ex1():
    print("函数内部访问全局变量:", n)

ex1()
print("函数外部访问全局变量:", n)

# 示例2:使用 global 关键字修改全局变量
n = 100

def ex2():
    global n  # 使用 global 关键字,告诉 Python 我要用外部的全局变量 n
    n = n * 2
    print("函数内部修改后的全局变量:", n)

ex2()
print("函数外部修改后的全局变量:", n)

# 示例3
m = "这是全局变量的值"

def ex3():
    n = "这是局部变量的值"
    print(n)
    print(m)

ex3()
print(m)

▶ 运行结果:

输出
函数内部访问全局变量: 50
函数外部访问全局变量: 50
函数内部修改后的全局变量: 200
函数外部修改后的全局变量: 200
这是局部变量的值
这是全局变量的值
这是全局变量的值

嵌套作用域(Enclosing Scope)—— 也称为闭包作用域

嵌套作用域存在于嵌套函数中,内层函数可以访问外层函数的变量,但外层函数不能访问内层函数的变量。当内层函数定义时,它会记住外层函数的变量环境。

python
# 示例1
def t1():
    t = 20

    def t2():
        print("内层函数访问外层函数的变量:", t)

    t2()

# t2()  # 在嵌套函数外不能调用内层函数
t1()
# print(t)  # 这会导致 NameError,t 变量在函数 t1 外部不可见

# 示例2:使用 nonlocal 关键字
def t2():
    num = 10

    def t3():
        nonlocal num  # nonlocal 关键字用于在嵌套函数中,声明变量来自于
                       # 外层(但非全局)函数的作用域,使得在内层函数中
                       # 可以修改外层函数中变量的值。
        num = num + 5
        print("内层函数修改后的外层变量:", num)

    t3()
    print("外层函数中修改后的变量:", num)

t2()

# 示例3
def t3():
    name = "你的名字是"

    def t4():
        new_name = name + " 小明"
        print(new_name)

    t4()
    # print(new_name)  # 这会导致 NameError,new_name 在内层函数外部不可见

t3()

▶ 运行结果:

输出
内层函数访问外层函数的变量: 20
内层函数修改后的外层变量: 15
外层函数中修改后的变量: 15
你的名字是 小明

内置作用域(Built-in Scope)

内置作用域包含了 Python 内置的函数、类型和变量等,例如 printlenint 等。这些内置对象在整个程序中都可以直接访问。

python
# 示例1:展示内置函数 len 的使用
print(len([1, 2, 3]))

# 示例2:展示内置函数 int 的使用
num = int("10")
print(num)

# 示例3:演示临时覆盖打印行为,并在使用后恢复的过程
def override_print():
    original_print = print

    def my_print(*args, **kwargs):
        original_print("自定义的打印函数,实际打印内容: ", end="")
        original_print(*args, **kwargs)

    return my_print

new_print = override_print()
new_print("Hello, World!")
# print("这是原始的print函数输出")

▶ 运行结果:

输出
3
10
自定义的打印函数,实际打印内容: Hello, World!