通过 LEGB 规则掌握 Python 范围Scope

发布时间:2023年12月29日

通过 LEGB 规则掌握 Python 范围(Master Python Scope by the LEGB Rule)

Introduction 导言

变量作用域variables scope(或 命名空间namespace)是编程语言中一个非常基本的概念。每个开发人员,无论使用哪种语言,都知道局部变量local variables和全局变量global variables的定义。然而,在 Python 中,情况变得有些复杂。以下问题在 Python 开发人员的面试中出现过很多次:

  • 为什么Python需要非局部nonlocal关键字?
  • 什么是 LEGB 规则?
  • Python 中 全局变量global variables 和 非局部变量nonlocal variables 的区别?
  • Python 中有多少种变量variables?

本篇文章将由浅入深地讲解 Python 的作用域scope。阅读后,您将完全掌握这一重要概念。

四类变量和 LEGB 规则 Four Types of Variables and the LEGB Rule

LEGB 规则定义了 Python 解释器interpreter检索变量名的顺序。这四个字母代表 Python 中的四种变量variables类型:

  • 局部变量Local Variables (L): 函数中的变量Variables in a function
  • 闭包变量或封闭变量Enclosed Variables (E): 在嵌套函数的上下文中In the context of nested functions
  • 全局变量 Global Variables(G):最上层变量The uppermost level variables
  • 内置变量 Built-in Variables (B): Python内置模块中的变量Variables in Python built-in modules

在这里插入图片描述

在程序中调用命名变量时,将在本地local、封闭enclosing、全局global和内置built-in作用域中scope依次检索对应的变量。如果命名变量存在,那么将使用第一个出现的变量。否则,将引发错误 raise error。

让我们来看一个例子:

name = "Zhang"

def print_name():
    name = "Python Guru"
    print(name)
print_name()  # Python Guru
print(name)  # Zhang

如上例所示,函数function print_name() 调用了局部变量local variable name 。函数function print() 调用了全局变量global variable name

掌握全局关键词Global Keyword

如果我们要修改函数function中的全局变量global variable name ,则需要使用 global 关键字keyword的语句statement。

name = "Zhang"

def print_name():
    global name
    name = "Python Guru"
    print(name)

print_name()  # Python Guru
print(name)  # Python Guru

掌握非局部关键字Nonlocal Keyword

封闭变量enclosing variables的概念是在嵌套函数nested functions的上下文中提到的。对于内层函数inner functions来说,外层函数outer functions中的变量既不是局部变量local variables,也不是全局变量global variable,而是 非局部变量nonlocal variables也称为封闭变量enclosing variables。例如:

name = "Zhang"  # global variable

def outer_func():
    name = "Python Guru"  # enclosing variable

    def inner_func():
        name = "Tech Leader"  # local variable
        print(name)

    inner_func()  # inner_func prints its local variable
    # will print "Tech Leader"
    print(name)  # print the enclosing variable
    # will print "Python Guru"
    return

outer_func()
# Tech Leader
# Python Guru
print(name)  # print the global variable
# Zhang

如上所示,三个不同的名称代表三种不同类型的变量variables,它们由 LEGB 规则调用。

如果我们想在内部函数inner function中更改非本地变量nonlocal variable的值,则需要使用 nonlocal 关键字。

name = "Zhang"  # global variable

def outer_func():
    name = "Python Guru"  # enclosing variable

    def inner_func():
        nonlocal name
        name = "Tech Leader"  # local variable
        print(name)

    inner_func()  # inner_func prints its local variable
    # will print "Tech Leader"
    print(name)  # print the enclosing variable
    # will print "Tech Leader"!!!
    return

outer_func()
# Tech Leader
# Tech Leader
print(name)  # print the global variable
# Zhang

该语句与 global 关键字语句一样简单。

Conclusion结论

LEGB 规则定义了 Python 查找变量的顺序。

如果我们要在函数中改变全局变量global variable,需要 global 语句。

如果我们要在内部函数inner function中改变非局部变量nonlocal variables也称为封闭变量enclosing variables(你也可以理解为外层变量),则需要 nonlocal 语句。

文章来源:https://blog.csdn.net/JENREY/article/details/135293579
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。