zoukankan      html  css  js  c++  java
  • Python基础知识补充(重要)-作用域、特殊语法

    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时候需要注意!!!
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    每日一水 POJ8道水题
    编译和使用 MySQL C++ Connector
    j2ee model1模型完成分页逻辑的实现 详解!
    DB查询分析器访问EXCEL时,要在表名前后加上中括弧或双引号
    指向结构体变量的指针
    EOSS V3.0 企业运营支撑系统(基于RBAC原理的权限管理)
    MybatisGen1.0 Mybatis JavaBean Mapper生成工具
    The table name must be enclosed in double quotation marks or sqare bracket while accessing EXCEL by
    资源-Android:Android
    软件-开发软件:Android Studio
  • 原文地址:https://www.cnblogs.com/jasonwang-2016/p/5664450.html
Copyright © 2011-2022 走看看