ZetCode

Python 变量遮蔽

最后修改日期:2025 年 2 月 26 日

变量遮蔽发生在当一个在特定作用域(例如,函数或代码块)中声明的变量与在更外层作用域中声明的变量同名时。这可能导致混淆和错误,因为内部变量“遮蔽”了外部变量,使得外部变量在内部作用域中无法访问。本教程涵盖了 Python 中的变量遮蔽,包括示例和避免它的最佳实践。

当局部作用域(例如,函数内部)中的变量与外部作用域(例如,全局作用域或包含作用域)中的变量同名时,就会发生变量遮蔽。局部变量“遮蔽”了外部变量,使其在局部作用域内无法访问。这可能导致代码中出现意外行为和错误。

局部作用域中的遮蔽

此示例演示了局部作用域(函数内部)中的变量遮蔽。

local_shadowing.py
x = 10  # Global variable

def my_function():
    x = 20  # Local variable shadows the global variable
    print(f"Local x: {x}")

my_function()
print(f"Global x: {x}")

# Output:
# Local x: 20
# Global x: 10

在此示例中,`my_function` 函数内的局部变量 `x` 遮蔽了全局变量 `x`。全局变量在函数外部保持不变。

嵌套函数中的遮蔽

此示例演示了嵌套函数中的变量遮蔽。

nested_shadowing.py
x = 10  # Outer scope variable

def outer_function():
    x = 20  # Enclosing scope variable

    def inner_function():
        x = 30  # Local variable shadows the enclosing scope variable
        print(f"Inner x: {x}")

    inner_function()
    print(f"Outer x: {x}")

outer_function()
print(f"Global x: {x}")

# Output:
# Inner x: 30
# Outer x: 20
# Global x: 10

在此示例中,`inner_function` 中的局部变量 `x` 遮蔽了 `outer_function` 中包含作用域的变量 `x`。每个作用域都维护着自己的 `x` 值。

循环中的遮蔽

此示例演示了循环中的变量遮蔽。

loop_shadowing.py
x = 10  # Global variable

for x in range(5):  # Loop variable shadows the global variable
    print(f"Loop x: {x}")

print(f"Global x: {x}")

# Output:
# Loop x: 0
# Loop x: 1
# Loop x: 2
# Loop x: 3
# Loop x: 4
# Global x: 4

在此示例中,循环变量 `x` 遮蔽了全局变量 `x`。循环结束后,全局变量保留了分配给循环变量的最后一个值。

类属性中的遮蔽

此示例演示了类属性中的变量遮蔽。

class_shadowing.py
x = 10  # Global variable

class MyClass:
    x = 20  # Class attribute shadows the global variable

    def print_x(self):
        print(f"Class x: {self.x}")
        print(f"Global x: {x}")

obj = MyClass()
obj.print_x()

# Output:
# Class x: 20
# Global x: 10

在此示例中,类属性 `x` 遮蔽了全局变量 `x`。通过直接使用其名称仍然可以访问全局变量。

列表推导式中的遮蔽

此示例演示了列表推导式中的变量遮蔽。

list_comprehension_shadowing.py
x = 10  # Global variable

# List comprehension variable shadows the global variable
squares = [x ** 2 for x in range(5)]  
print(f"Squares: {squares}")
print(f"Global x: {x}")

# Output:
# Squares: [0, 1, 4, 9, 16]
# Global x: 10

在此示例中,列表推导式中的变量 `x` 遮蔽了全局变量 `x`。列表推导式之后,全局变量保持不变。

避免遮蔽的最佳实践

来源

Python 作用域和命名空间文档

在本文中,我们探讨了 Python 中的变量遮蔽,并通过实际示例演示了它在不同作用域中的出现。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直撰写编程文章。至今,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出所有 Python 教程