码迷,mamicode.com
首页 > 编程语言 > 详细

Python基础知识补充(重要)-作用域、特殊语法

时间:2016-07-12 19:27:02      阅读:332      评论:0      收藏:0      [点我收藏+]

标签:

Python作用域

python代码内部块如if语句内声明变量,在if代码段后在调用此变量并未报如“undefinded name"此类错误,例子如下:

if 1 == 1:
    name = Jason
print(name)

##result
Jason

 

如果在java和c#中,会抛出异常,而在python和javascript中均无报错,这正是因为python和javascript中无块级作用域

  • 在有块级作用域的语言中,比如java/c#,代码中的name只在当前作用域下生效。
  • 在没有块级作用域的语言中,比如python/javascript中,代码中的name变量,不仅在代码块中生效,在代码块外面也一样生效

python中函数中定义变量,函数执行后,外部调用,是怎样的情况呢?例子如下:

def func():
    name = Jason

func()
print(name)

##result
    print(name)
NameError: name name is not defined

在函数的作用域中,变量无法生效的。

python中有作用域链,对于变量的查找方式是由内向外查找的,当前作用域中有,使用当前变量设置,如果没有,往外查找,直到找到最后找不到而报错。

看个例子能更为直观些:

name=outer
def f1():
    name=f1
    def f2():
        name = f2
        print(name)
    f2()
f1()

##result
f2

 

按照上面所说的查找规则,先从f2中查找name,f2中name的值为f2,正如执行结果,若果f2内没有name变量,则向外查f1内是否有,若没有则在f1外查找,找到为止,未找到则报错

python/javascript中作用域与函数的关系

对于作用域来说,在函数没有执行之前,他的作用域、作用域链均已经确定。
看下例子:

name = Jason


def f2():
    name = eric
    f1()
def f1():
    print(name)
f2()
##result
Jason
def f1():
    print(name)
def f2():
    name = eric
    return f1
ret = f2()
ret()
##result
Jason

 

以上两段代码,执行结果一致,这是Python一个很容易掉进的坑,在作用域1中,作用域会直接用使用全局变量name=‘Jason‘,但在作用域2中,虽然有一个局部变量name,但在程序最终执行之前,python已经从上到下把作用域和作用域链确定了,就是f1()的执行结果肯定是Jason,不受其他因素的影响。
 

Python特殊用法tip

li=[x+100 for x in range(10)]   #在0-9循环,并且每次循环+100
print(li)
lis=[x+100 for x in range(10) if x > 6]     #只有x>6时,x+100
print(lis)

li1=[lambda: x for x in range(10)] #首先li是一个列表,列表中的元素都是函数
print(li1)
# print(type(li1))
r=li1[0]()      #函数加括号执行lambda表达式
print(r)        #最后x为9,所以每个元素都是return 9

 

output:
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
[107, 108, 109]
[<function <listcomp>.<lambda> at 0x0000019EC393D598>, <function <listcomp>.<lambda> at 0x0000019EC393D620>, <function <listcomp>.<lambda> at 0x0000019EC393D6A8>, <function <listcomp>.<lambda> at 0x0000019EC393D730>, <function <listcomp>.<lambda> at 0x0000019EC393D7B8>, <function <listcomp>.<lambda> at 0x0000019EC393D840>, <function <listcomp>.<lambda> at 0x0000019EC393D8C8>, <function <listcomp>.<lambda> at 0x0000019EC393D950>, <function <listcomp>.<lambda> at 0x0000019EC393D9D8>, <function <listcomp>.<lambda> at 0x0000019EC393DA60>]
9

 python lamda函数用于定义一些简单函数,如加减等,例子如下:

def lambda():
    return x
##li中lambda函数只是如上面定义的函数,返回x,与后面的for循环无直接联系,当for循环结束后,x值为9,付给lambda函数,最终li列表的第一个值为9
li = [lambda :x for x in range(10)]

其实把他拆开,我们可以这么写一行:

li = []
for i in range(10)
    def f1():
        return i
    li.append(f1)
print(li[1]())
##result
9

 

首先for 循环已完成,i已经赋予9,然后f1()执行时,按照作用域链查找,i=9,那么返回就是9了。
那么如果对f1中的x赋值会怎样:
li = []
for i in range(10)
    def f1(x=i):
        return x
    li.append(f1)
print(li[0]())
print(li[1]())
print(li[2]())

 output:

0
1
2

为什么呢,因为x=i是一个表达式,表达式是执行了函数。所以还是要看他的本质,要看函数是否被执行

总结
总结下这篇的重要的三句话吧:

python中是以函数作为作用域的,并且python中无块级作用域
对于作用域来说,在函数没有执行之前,他的作用域、作用域链均已经确定。,并且:对于变量的查找方式是由内向外查找的,当前作用域中有,使用当前变量设置,如果没有,往上查找,知道找到最后找不到而报错。
函数在没执行前,内部代码不执行。在碰到lambda时候需要注意!!!

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Python基础知识补充(重要)-作用域、特殊语法

标签:

原文地址:http://www.cnblogs.com/jasonwang-2016/p/5664450.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!