Python基础之函数二

  函数的嵌套

  通过名字就能理解,函数里是还可以套着函数用的。这么牛,下面就来看看几段代码,看看是怎么回事。注意:函数一定是先定义后使用。

x=1234
def f1(): #定义一个主函数
    x = 1 
    print('f1---> ', x)
    def f2(): #主函数下的嵌套函数
        x = 2
        print('f2-----> ', x)
        def f3(): #主函数下的嵌套函数
            x = 3
            print('f3-------> ', x)
        f3() #调用函数f3
    f2()#调用函数f2

f1() #调用主函数
    f1---> 1 #以下是输出的结果
    f2-----> 2
    f3-------> 3

  函数的特性:

  1、函数可以被赋值

def foo(): #创建一个函数
     print('foo')
 f=foo #给变量名为f的赋值为foo函数
 print(f)
 f() #变量名可以直接调用函数等同于发f()=foo()

  2、可以把函数当成参数传递

def bar(func):#func=foo的值,给函数传参数
     print(func)
     func()
 bar(foo)#foo是上面那个函数的返回值

  3、可以把函数当成返回值

def bar(func):
     print(func)
     return func

f=bar(foo) #将foo的值传给func
print(f)
f()
<function foo at 0x0000000002133E18> #打印func的内存地址和foo的一致
foo #f的值

  4、把函数当做容器类型的元素去用(这个就不用举例了,像列表、元组、字典等容器)

  名称空间与作用域  

  名称空间是名称(标识符)到对象的映射。

  向名称空间添加名称的操作过程涉及到绑定标识符到指定对象的操作(以及给该对象的引用计数加 1 )。

  名称空间分为:

  1、内置名称空间

  2、全局名称空间

  3、局部名称空间

  作用域分为:

  1、L:local,局部作用域,即函数中定义的变量;

  2、E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;

  3、G:globa,全局变量,就是模块级别定义的变量;

  4、B:built-in,系统固定模块里面的变量,比如int, bytearray等。

  搜索变量的优先级顺序依次是:

  作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是L>E>G>B。

   闭包

  闭包:首先必须是内部定义的函数,该函数包含对外部作用域而非全局作用域定义变量的引用。

x=1234 #x为全局作用域
def f1(): #定义一个主函数  f1函数名为全局作用域
    x = 1 
    print('f1---> ', x)
    def f2():  #f2为这个函数的局部作用域
        x = 2
        print('f2-----> ', x)
        def f3():  #f3为这个函数的局部作用域
            print('f3-------> ', x)
        f3() #调用函数f3
    f2()#调用函数f2

f1() #调用主函数
    f1---> 1 #以下是输出的结果
    f2-----> 2
    f3-------> 2 #这个值就是调用的父级函数变量名的值

  总结:因为上面我们清楚了作用域搜索变量的优先顺序,在父级函数能匹配到对应的变量名的值,so,这个全局作用域的x的值形同虚设。没有引用到全局作用域的变量名的值,这就是闭包。

 

posted @ 2017-04-07 17:15  Michael--chen  阅读(248)  评论(0编辑  收藏  举报