zoukankan      html  css  js  c++  java
  • 课时20:内嵌函数和闭包

    目录:

      一、global关键字

      二、内嵌函数

      三、闭包

      四、课时20课后习题及答案

    ********************

    一、global关键字

    ********************

    全局变量的作用域是整个模块(整个代码段),也就是代码段内所有的函数内部都可以访问到全局变量。但是要注意一点,在函数内部仅仅去访问全局变量就好,不要试图去修改它。

    因为那样的话,Python会使用屏蔽的方式”保护“全局变量:一旦函数内部试图修改全局变量,Python就会在函数内部自动创建一个名字一模一样的局部变量,这样修改的结果只会修改到局部变量,而不会影响到全局变量。看下面的例子:

    >>> count=5
    >>> def myFun():
        count = 10
        print(count)
    
        
    >>> myFun()
    10
    >>> count
    5

    如果觉得有必要在函数中去修改这个全局变量,那么你不妨可以使用global关键字来达到目的!修改程序如下:

    >>> count=5
    >>> def myFun():
        global count
        count = 10
        print(count)
    
        
    >>> myFun()
    10
    >>> count
    10

    二、内嵌函数

    ****************

     Python函数定义是可以嵌套的,也就是允许在函数的内部创建另外一个函数,这种函数叫做内嵌函数或者内部函数。举个例子:

    >>> def fun1():
        print("fun1()正在被调用")
        def fun2():
            print("fun2()正在被调用")
        fun2()
    
        
    >>> fun1()
    fun1()正在被调用
    fun2()正在被调用

    值得注意的是:就是内部函数整个作用域都在外部函数之内。

    另外需要注意的地方:如果在fun1()外部试图调用内部函数fun2(),就会报错:

    >>> fun2()
    Traceback (most recent call last):
      File "<pyshell#45>", line 1, in <module>
        fun2()
    NameError: name 'fun2' is not defined

    ***********

    三、闭包

    ***********

     闭包是函数编程的一个重要的语法结构,函数式编程是一种编程范式,著名的函数式编程语言就是LISP语言。

    Python中闭包从表现形式上定义为:如果在一个内部函数内(funY就是这个内部函数),对外部作用域(但不是在全局作用域)的变量进行引用(x就是被引用的变量,x在外部作用域funX里面,但不在全局作用域里),那么内部函数就被认为是闭包。

    >>> def funX(x):
        def funY(y):
            return x*y
        return funY
    
    >>> i = funX(8)
    >>> i
    <function funX.<locals>.funY at 0x0000017296857488>
    >>> type(i)
    <class 'function'>
    >>> type(funX)
    <class 'function'>
    >>> funX
    <function funX at 0x0000017296857598>
    >>> i(5)
    40

    也可以直接这样写:

    >>> funX(8)(5)
    40

    使用闭包时,需要注意的是:因为闭包的概念就是由内部函数而来的,所以也不能在外部函数以外的地方对内部函数进行调用:

    >>> funY(5)
    Traceback (most recent call last):
      File "<pyshell#58>", line 1, in <module>
        funY(5)
    NameError: name 'funY' is not defined

    在闭包中,外部函数的局部变量对应内部函数的局部变量,实际上就相当于之前讲的全局变量跟局部变量的关系,在内部函数中,你只能对外部函数的局部变量进行访问,但不能进行修改。

    >>> def funX():
        x = 5
        def funY():
            x *= x
            return x
        return funY
    
    >>> funX()()
    Traceback (most recent call last):
      File "<pyshell#61>", line 1, in <module>
        funX()()
      File "<pyshell#60>", line 4, in funY
        x *= x
    UnboundLocalError: local variable 'x' referenced before assignment

    这个错误信息跟之前讲解全局变量的时候基本一样,Python认为在内部函数的x是局部变量的时候,外部函数的x就被屏蔽了起来,所以执行x *= x的时候,在右边根本找不到局部变量x的值,因此报错。

    在Python3以前并没有直接的方案进行解决,只能间接的通过容器类型来存放,因为容器类型不是放在栈里,所以不会被‘屏蔽’掉。

    >>> def funX():
        x = [5]
        def funY():
            x[0] *= x[0]
            return x[0]
        return funY
    
    >>> funX()()
    25

    在Python3里有了改进。如果希望在内部函数里可以修改外部函数里的局部变量的值,用关键字nonlocal。

    >>> def funX():
        x = 5
        def funY():
            nonlocal x
            x *= x
            return x
        return funY
    
    >>> funX()()
    25

    扩展阅读-->游戏中的移动角色:闭包在实际开发中的作用:(地址是:https://fishc.com.cn/thread-42656-1-1.html

    *******************************

    四、课时20课后习题及答案

    *******************************

     

    爱笑的男孩运气都不会差
  • 相关阅读:
    第08组 Alpha冲刺(1/6)
    第08组 团队Git现场编程实战
    第08组 团队项目-需求分析报告
    团队项目-选题报告
    第二次结对编程作业
    第一次结对编程作业
    第8组 团队作业
    第一次个人编程作业
    第一次博客作业
    Alpha 冲刺 (7/10)
  • 原文地址:https://www.cnblogs.com/DC0307/p/9473305.html
Copyright © 2011-2022 走看看