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
本文出自 “麻婆豆腐” 博客,请务必保留此出处http://beanxyz.blog.51cto.com/5570417/1861879
原文地址:http://beanxyz.blog.51cto.com/5570417/1861879