Python中的变量作用域

时间:2022-11-02 06:06:33

来源: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的值因为它还没有调用~也就是还没执行~