Python的作用域和其他语言有所不同,他有几个小窍门来判断作用域。


1. Python里面没有块级别的作用域;只有函数级别的作用域。


比如说,下面这个例子,如果是Java或者其他语言,肯定报错name没有定义。Python里面因为不存在块级别的作用域,因此name直接就输出9了

>>> for i in range(10):
    name=i
print(name)
----------
9


2. 作用域链的顺序是从内往外找,直到找不到为止

例如

>>> def f1():
    name='a'
    def f2():
        name='b'
        print(name)
    f2()
    print(name)
f1()
--------------
b
a


3. 函数没有执行之前,作用域已经确定了,作用域链也已经确定了。

例如 f0()执行之前,已经确定了name就是alex,因此不管他如何调用,输出总是alex

>>> name='alex'
def f0():
    print(name)
def f1():
    name='bbb'
    f0()
def f2():
    name='eric'
    f1()
f2()
-----------------
alex


下面看几个特殊的例子和语法


比如,我们可以通过下面的方式给列表赋值

>>> li=[x+100 for x in range(10)]
print(li)
li=[x+100 for x in range(10) if x>6]
print(li)
------------
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
[107, 108, 109]


如果把上面的例子改成lambda表达式,那么因为lambda其实就是函数,他在未执行前是不会执行内部代码的,因此列表里面的每个元素都是函数,当我们()来执行的时候,他会尝试返回X,而X这个时候在10次循环之后已经是9了

>>> #li列表里面的元素[函数,函数,函数],函数在没有执行前,内部代码不执行
li=[lambda :x for x in range(10)]
print(li)
print(li[0]())
-----------------
[<function <listcomp>.<lambda> at 0x0000019EA4515BF8>, <function <listcomp>.<lambda> at 0x0000019EA4515C80>, <function <listcomp>.<lambda> at 0x0000019EA4515D08>, <function <listcomp>.<lambda> at 0x0000019EA4515D90>, <function <listcomp>.<lambda> at 0x0000019EA4515E18>, <function <listcomp>.<lambda> at 0x0000019EA4515EA0>, <function <listcomp>.<lambda> at 0x0000019EA4515F28>, <function <listcomp>.<lambda> at 0x0000019EA452B048>, <function <listcomp>.<lambda> at 0x0000019EA452B0D0>, <function <listcomp>.<lambda> at 0x0000019EA452B158>]
9



换一种容易理解的写法。


>> li=[]
for i in range(10):
    def f1():
        return i
    li.append(f1)
#li是列表,内部元素是相同功能的函数
#i=9
print(i)
## f1 没有调用之前,内部代码不执行;因此li内部都是函数
##真正执行() 时候,他会返回i,内部没有i,往上找,i已经是9了,因此返回9
print(li[0]())
print(li[2]())
9
9


如果改成x=i,f1初始化的时候会指定x的值

>>> li=[]
for i in range(10):
    def f1(x=i):
        return x
    li.append(f1)
#li是列表,内部元素是相同功能的函数
#i
print(i)
## f1 没有调用之前,内部代码不执行;因此li内部都是函数
##真正执行() 时候,他会返回i,内部没有i,往上找,i已经是9了,因此返回9
print(li[0]())
print(li[2]())
9
0
2