1、块级作用域
1 if 1 == 1:2 name = "lzl"
3
4 print(name) //输出lzl5
6
7 for i in range(10):8 age =i9
10 print(age) //输出9
在Java/C#中,执行上面的代码会提示name,age没有定义,而在Python中可以执行成功,这是因为在Python中是没有块级作用域的,代码块里的变量,外部可以调用,所以可运行成功
2、局部作用域
1 deffunc():2 name = "lzl"
3
4 print(name) //抛出异常
name变量只在func()函数内部中生效,所以在全局中是没法调用的
3、作用域链
1 name = "lzl"
2 deff1():3 name = "Eric"
4 deff2():5 name = "Snor"
6 print(name)7 f2()8 f1() //输出Snor
Python中有作用域链,变量会由内到外找,先去自己作用域去找,自己没有再去上级去找,直到找不到报错
4、终极版作用域o( ̄▽ ̄)d
1 name = "lzl"
2
3 deff1():4 print(name)5
6 deff2():7 name = "eric"
8 f1()9
10 f2() //输出lzl
这一段代码可以做如下理解:
1 name = "lzl"
2
3 deff1():4 print(name)5
6 deff2():7 name = "eric"
8 returnf19
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 #
5 #
可以看到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的值因为它还没有调用~也就是还没执行~