Python作用域
1 if 1==1: 2 name="alex" 3 print(name) #print 能打印出值么?
1.上边例子输出"alex",表示在python中无块级作用域。而在java或C#中会报错:未定义变量。
2.python以函数为作用域。
1 def func(): 2 name = "alex" 3 4 print(name) # 未定义
3.Python有自己作用域链,由内向外一次寻找。
1 name = 'alex' # 全局作用域 2 def f1(): 3 name = 'a' # 作用域f1->全局 4 def f2(): 5 name = 'b' # 作用域 f2->f1->全局 6 print(name) 7 f2() 8 9 f1() #会输出什么? 将f2的name注释又会输出什么,将f1的name注释又会输出什么
如果你已经明白了Python作用域,那么下边的事例输出什么?
1 name = "alex" 2 def f1(): #作用链 f1->全局 3 print(name) 4 5 def f2(): # 作用域f2->全局 6 name = "eric" 7 f1() 8 f2()
4.上边例子告诉我们:作用域在函数被定义或变量被定义时,即程序运行前就已经被确定了。
==========================================================
插播一个企业面试题:下边表达式执行结果是什么呢?
1 #列表生成式 2 li = [x+1 for x in range(10)] 3 # [1,2,3,4,5,6,7,8,9] 4 li = [x+1 for x in range(10) if x>6] 5 # [8,9,10] 6 # 问题来了。。。。print 输出结果 7 li = [lambda :x for x in range(10)] 8 print(li) 9 re1 = li[0]() 10 re2 = li[1]() 11 re3 = li[2]() 12 print(re1,re2,re3)
解析:
"lambda :x" 相当于函数 def f():return x ;
首先,我们要知道函数没有被调用前,是不执行内部代码的。所以在列表生成式里,li内存放的是函数名,即函数地址。像li=[函数,函数,函数....];
第二,函数 返回值x 在函数内部并没有定义,也没有执行。for表达式执行后,x值为9;
第三,此时调用li[0]()相当于执行函数体,而此时x值为9,所以li[]()返回值为9。
1 li = [] 2 for i in range(10): 3 def f1(): 4 return i 5 li.append(f1)
变种题:
1 # print 输出什么 2 li = [] 3 for i in range(10): 4 def f1(x=i): 5 return x 6 li.append(f1) 7 8 print(li[0]()) 9 print(li[1]()) 10 print(li[2]())
解析:
参数x=i是被执行了,每一次都接受传参并赋值给x。所以最后函数执行的结果就是0,1,2.