LCY.SEN

导航

 

Python作用域

1 if 1==1:
2     name="alex"
3 print(name) #print 能打印出值么?
例子1

1.上边例子输出"alex",表示在python中无块级作用域。而在java或C#中会报错:未定义变量。

2.python以函数为作用域。

1 def func():
2     name = "alex"
3 
4 print(name) # 未定义
例子2

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注释又会输出什么
例子3

如果你已经明白了Python作用域,那么下边的事例输出什么?

1 name = "alex"
2 def f1(): #作用链 f1->全局
3     print(name)
4 
5 def f2(): # 作用域f2->全局
6     name = "eric"
7     f1()
8 f2()
例子4

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.

posted on 2017-05-17 15:29  LCY.SEN  阅读(186)  评论(0编辑  收藏  举报