Python里作用域的复习

首先,Python 变量作用域的规则是 LEGB

这个可以参考下边这篇博客。https://www.cnblogs.com/yvivid/p/python_LEGB_1.html
个人比较喜欢用程序来进行理解。

def num():
    lt = []
    i = 10
    for i in range(4):

        def a(x):
            # print(i)
            return(x * i)
        lt.append(a)
    print(u"num 中I 的值为",str(i))
    return lt


# print(num())
for x in num():
    print(x(3))
# python 中,函数不执行的话,就是一个引用而已,函数的名字 对应的指向函数代码块的内存地址。
# 在向lt中添加a的时候,只是添加了函数a的的代码块的引用。 然后在print语句中牵扯到了执行,执行的时候a函数作用域咩有i,
# 所以要向上一层去找i, 找的时候 num()函数是执行结束的,所以内部的for循环也是执行结束的,所以只能找到最后的i 也就是3.
# 当lt中的函数未执行时,只是四个引用,执行的时候才去获取值运行,x是传递的参数。i要通过作用域去寻值


# 当一个函数被另一个模块引用时,如果该函数有使用到自己模块内的全局变量时.
# 模块间变量的调用。https://punchagan.muse-amuse.in/blog/python-globals/

test_a = 4
def test():
    print("====1"  # 错误时只能将这里打印出来
    print(test_a)  # 只打印是可以的。
    # b = test_a + 1  # 这样可以
    # test_a = 4
    print("====2")
    test_a = test_a + 1  # 不能赋值,如果未加说明而在函数内对一个变量赋值,那么就认为你定义了一个局部变量,从而把外部的同名对象屏蔽了。上边的打印也会出错。python代码在执行前首先会被编译成字节码,这就会导致某些时候实际执行的程序会和我们看到的产生出入。
    # print(b)

# test_a = [1,2,3]
# def test():
#     print(test_a)
#     test_a.append(4)  # 这样可以 这样的操作并没有产生赋值语句。
#                       # 可变对象与不可变对象改变时。可变对象内存地址没有发生改变,不可变对象地址改变
#     print(test_a)


def test_2():
    # global test_a
    test_a = 5
    test()
test_2()


exit()
i = 0
def f():
  print(i)
  i += 1
  print(i)

f()
print(i)

# ==> UnboundLocalError: local variable 'i' referenced before assignment

# python对函数的代码是独立编译的,如果未加说明而在函数内对一个变量赋值,那么就认为你定义了一个局部变量,从而把外部的同名对象屏蔽了。
# 这么做无可厚非,毕竟python没有独立的声明一个局部变量的语法,但结果就会造成我们看到的类似暂时性死区的现象。https://www.cnblogs.com/apocelipes/p/10408836.html
原文地址:https://www.cnblogs.com/dg-blog/p/12692743.html