Python 搞定Python中的作用域
转载请标明出处(http://blog.csdn.net/lis_12/article/details/52915711).
阅读前,请谨记以下两句:
- ,函数在没有执行前,内部代码不执行;
- 在函数未执行前,作用域就已经生成了,作用链也生成了;
块级作用域
for i in range(10):
print i
print i #9
if 1 == 1:
name = 'lz'
print name #lz
if 2 > 2:
name1 = 'lz0' #代码块里的变量
print name1 #error,NameError: name 'name1' is not defined
Python不像C语言一样,如
for(int i = 0;i < 10;i++)
{
dosomething();
}
print("%d\n",i);#error,i只能在for中使用
Python中是没有块级作用域的,外部也是可以调用的,但是如果代码块里面的变量没有执行的话,外部就不能使用代码块里的变量.见上述Python代码.
局部作用域
def fun():
a = 10
fun()
print a #error,a仅在fun()函数内有效,在外部是无法调用的,(将变量声明为全局变量除外)
作用域链
#作用域链
name = 'lz'
def fun():
name = 'lz0'
def fun2():
name = 'lz1'
print name
fun2()
fun() #'lz1'
Python中有作用域链,变量会由内到外的找,先去在本身的作用域找,如果未找到,则取上级作用域找,直至找到为止,如果到了最顶层扔未找到则抛出异常.
终极版1
name = 'lz'
def f1():
print name
def f2():
name = 'lz0'
return f1
f = f2()
f() #结果是啥呢?
f2()返回了函数f1的内存地址,执行f()等同于执行f1(),f1()和f2()并没有任何关系,所以当执行f1()的时候,如果函数内找不到变量则会向外部寻找,所以执行f()的结果为’lz’.
终极版2
name = 'lz'
def f1():
print name
def f2():
name = 'lz0'
f1()
f2() #lz
请记住,在函数未执行前,作用域就已经生成了,作用链也生成了…..
终终极版
l = [lambda : x for x in range(10)] #相当于无入参的函数
print type(l) #list
print l[0] #<function <lambda> at 0x00000000034FD7B8>
print l[0]() #结果是?
结果是9- -!,不是0,懵逼了……
请记住,函数在没有执行前,内部代码不执行……来个简单点的例子…
#通俗版
def f():
global a
a = 10
print a #error,函数在未执行前,a还不是全局变量....
f()
print a #10
#进化版
x = 1
f1 = lambda :x
x = 2
f2 = lambda :x
x = 3
f3 = lambda :x
x = 4
f4 = lambda :x
print f1() #4
x = 5
print f2() #5,这下该理解"函数在没有执行前,内部代码不执行"这句话了吧....,f1()执行时,由于函数体内未定义x,向上寻找,此时x = 4,返回4;f2()执行时,,由于函数体内未定义x,向上寻找,此时x = 5,返回5