• Python10作用域、LEGB规则


    作用域就是一个 Python 程序可以直接访问命名空间的正文区域。

    在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。

    Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。

    变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:

    有四种作用域:

    • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
    • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
    • G(Global):当前脚本的最外层,比如当前模块的全局变量。
    • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

    搜索变量名的优先级: L –> E –> G –> B。(局部作用域>嵌套作用域>全局作用域>内置作用域)

    LEGB法则:当在函数中使用未确定的变量时,Python会按照优先级依次搜索4个作用域,以此来确定变量的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按照这换个查找原则,在第一处找到的地方停止。如果没有找到,则会触发NameError错误。在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

     1 #作用域
     2 a1 = 10          #全局作用域
     3 def pri():
     4     print(a1)
     5 pri()
     6 
     7 
     8 def pri1():
     9     a2 = 20       #局部作用域
    10     print(a2)
    11 pri1()
    12 #print(a2)        #这句这样写则会报错,因为a2的作用域只在函数内部并不是全局作用域,注意区别
    13 
    14 
    15 #嵌套作用域
    16 def f1():
    17     n = 10         #在f1函数中,是局部作用域 相对于f2函数,是嵌套作用域
    18     def f2():
    19         m = 20     #局部作用域
    20         print(n)
    21     f2()
    22 
    23 
    24 #内置作用域 系统自带
    25 print(__name__)   #内置作用域

     1 #搜索变量名的优先级:局部作用域>嵌套作用域>全局作用域>内置作用域
     2 #LEGB法则:当在函数使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,
     3 # 以此来确定该变量的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda
     4 # 函数的嵌套做作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按照这个查找原则,
     5 # 在第一处找到的地方停止。如果没有找到,则触发NameError错误。
     6 a1 = 10   # G
     7 def f1():
     8     a1 = 20  # E
     9     def f2():
    10         a1 = 30 # L
    11         print(a1)
    12     f2()
    13 f1()
    14 
    15 
    16 #********************************************
    17 a1 = 10   # G
    18 def f1():
    19     a1 = 20  # E
    20     def f2():
    21         # a1 = 30 # L
    22         print(a1)
    23     f2()
    24 f1()
    25 # ********************************************
    26 a1 = 10   # G
    27 def f1():
    28     # a1 = 20  # E
    29     def f2():
    30         # a1 = 30 # L
    31         print(a1)
    32     f2()
    33 f1()
    34 
    35 # ******************************************
    36 
    37 a2 =  100
    38 def f3():
    39     global a2             #使用global将全局变量a2的地址给引用过来了,就会改变全局变量的值
    40     a2 = 60
    41     print(a2)
    42 f3()
    43 print(a2)                 #查看全局变量a2确实是变了,变成了60

  • 相关阅读:
    OSI安全体系结构
    PHP 二维数组根据相同的值进行合并
    Java实现 LeetCode 17 电话号码的字母组合
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 14 最长公共前缀
  • 原文地址:https://www.cnblogs.com/yyym/p/16601378.html
Copyright © 2020-2023  润新知