来源:http://www.cnblogs.com/lianzhilei/p/5852959.html
1、块级作用域
1 if 1 == 1: 2 name = "lzl" 3 4 print(name) //输出lzl 5 6 7 for i in range(10): 8 age = i 9 10 print(age) //输出9
在Java/C#中,执行上面的代码会提示name,age没有定义,而在Python中可以执行成功,这是因为在Python中是没有块级作用域的,代码块里的变量,外部可以调用,所以可运行成功
2、局部作用域
1 def func(): 2 name = "lzl" 3 4 print(name) //抛出异常
name变量只在func()函数内部中生效,所以在全局中是没法调用的
3、作用域链
1 name = "lzl" 2 def f1(): 3 name = "Eric" 4 def f2(): 5 name = "Snor" 6 print(name) 7 f2() 8 f1() //输出Snor
Python中有作用域链,变量会由内到外找,先去自己作用域去找,自己没有再去上级去找,直到找不到报错
4、终极版作用域o( ̄▽ ̄)d
1 name = "lzl" 2 3 def f1(): 4 print(name) 5 6 def f2(): 7 name = "eric" 8 f1() 9 10 f2() //输出lzl
这一段代码可以做如下理解:
1 name = "lzl" 2 3 def f1(): 4 print(name) 5 6 def f2(): 7 name = "eric" 8 return f1 9 10 ret = f2() 11 ret()
f2()执行结果为函数f1的内存地址,即ret=f1;执行ret()等同于执行f1(),执行f1()时与f2()没有任何关系,name=“lzl”与f1()在一个作用域链,函数内部没有变量是会向外找,所以此时变量name值为“lzl”
5、面试题一道
1 li = [lambda :x for x in range(10)]
判断下li的类型?li里面的元素为什么类型?
1 print(type(li)) 2 print(type(li[0])) 3 4 # <class 'list'> 5 # <class 'function'>
可以看到li为列表类型,list里面的元素为函数,那么打印list里面第一个元素的返回值,此时返回值为多少?
1 li = [lambda :x for x in range(10)] 2 3 res = li[0]() 4 print(res) 5 6 #输出:9
li第一个函数的返回值为9还不是0,记住:函数在没有执行前,内部代码不执行;
解析:这是一个列表解析表达式,每个元素都是一个函数,每个函数返回的是x的值。for x in range(10)会循环10次,直到x=9结束,所以x的值是9,然后生成一个函数列表,每个函数的功能是返回x的值。
res = li[0]()
此时,调用函数列表中的第一个函数,也就是返回x的值,而x的值上面已经知道了就是9
所以最后输出的是9
所以最重要的一点就是,在列表解析式中,循环10次生成的只是函数,她不会返回x的值因为它还没有调用~也就是还没执行~