• python函数基础:嵌套函数、作用域、匿名函数、高阶函数、递归函数


    嵌套函数:

    1. 函数内部可以再定义函数

    2. 函数只有被调用之后才会执行

    看如下代码:

    age = 18
    
    def func1():
        age = 22
        print(age)
    
        def func2():
            age = 28    # 如果这个age没有被赋值,它会先向它的父级(func1)里面找,如果父级也没有就再向它的爷爷级(全局的age)找。  # 一层一层由内向外找
            print(age)
        func2()
    
    func1()
    
    # 输出结果:
    #22
    #28

    注: 函数内部的变量都叫局部变量,只不过局部变量之间也有等级关系

    #情景1:
    age = 18
    
    def func1():
    
        def func2():
            print(age)
        age = 22  # age=22 依然是func1里面的变量
        func2()   #程序从上到下运行到这一步的时候 age已经在函数内被赋值为22
    
    func1()
    
    #输出结果:
    # 22
    
    #情景2:
    age = 18
    
    def func1():
    
        def func2():
            print(age)
        func2()   #程序由上到下运行到这一步时,由于func2中没有age,func2会向上一级找,找到了func1中的age=22,但由于变量需要先定义后使用(定义放在使用前面),所以程序会报错。例如情景3
        age = 22  # age =22依然是函数func1里面的变量
    
    func1()
    
    # 输出结果会报错。
    
    #情景3:
    age = 18
    
    def func1():
    
        def func2():
            print(age2)
        func2()
        age2 = 22
    
    func1()
    
    # 输出结果会报错。
    
    #情景4:
    age = 18
    
    def func1():
        global age  #程序执行到这一步的时候,age已经被声明成了全局变量,并被赋值为18
        def func2():
            print(age)  #执行到这一步的时候age直接调用age这个全局变量
        func2()
        age = 22   #  程序执行到这一步的时候age这个全局变量又被赋值成了22
    
    func1()
    print(age)
    
    # 输出结果:
    # 18
    # 22
    
    #情景5:
    
    age = 18
    
    def func1():
        global age  #到这一步age被声明成全局变量,并且此时的值还是18
        age = 22   # 到这一步时age又被重新赋值为22
        def func2():
            print(age)
        func2()
      
    func1()
    
    #输出结果:
    # 22
    
    #情景6:
    age = 18
    
    def func1():
        global age #执行到这一步是age还是18
        def func2():
            print(age)   #执行到这一步的时候age已经是22了
        age = 22  # age这个全局变量 在func2调用之前又被改成了22
        func2()
    
    func1()
    
    # 输出结果:
    # 22

    注:这几种情况用于分析,实际生产中很少用。

    作用域:

    在Python中一个函数的就是一个作用域,局部变量其实是放在它的作用域中

    age = 18
    def func1():
        age = 22
        def func2():
            print(age)
    
        return func2   #func2没加括号,返回的是这个函数名
    
    val= func1()
    print(val)  #打印的是函数名
    val()     #val就是func2, 此时会执行
    
    # 输出结果:
    # <function func1.<locals>.func2 at 0x0000009F6AEAB9D8>
    # 22   #虽然是在外部执行,但依然是通过其定义域的关系去调用,所以不会是18.

    代码定义完成后,作用域就已经生成。以后调用时会通过其定义域关系向上查找(不管这个函数名是在哪里被调用,只要一执行,它还是会回来它定义的地方向上去查找。)。

    匿名函数:

    # 普通函数:
    def calc( x,y):
        return x*y
    # 匿名函数: 
    lambda x,y: x*y   #声明一个匿名函数 (把多行语句变成一行)

    调用:

    func = lambda x,y: x*y
    func(3,8)

    匿名函数最复杂的也只能进行三元运算。

    匿名函数通常跟其他的方法搭配使用,作用主要是节省代码量、如:

    # 要求: 使range(10)里面的数各自跟自己相乘
    
    data = list(range(10))
    print(list(map(lambda x:x*x,data)))
    
    # 输出结果:
    # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    
    # map的用法: map(func, *iterables) --> map object
    # 就是把iterables中的每一个值都进行一下前面的函数。
    # list(map())的作用是让map的结果变成列表的样子
    # iterables有:list,str,tuple,dict,file,xrange等

    返回值:

    # 匿名函数不需要return来返回值,表达式本身结果就是返回值。

    高阶函数:

    变量可以指向函数,函数的参数能够接收变量,一个函数可以接收另一个函数作为参数,这种函数就叫高阶函数。

    另外,一个函数return了另外一个函数,这个也是高阶函数,如:

    def func(x,y):
        return abs,x,y   # return 里面有abs, 是一个函数, 所以 func是高阶函数; 假如 return abs(x+y) 那func就不是高阶函数, 因为返回的是 abs(x+y),这是一个函数的结果, 不是函数。
    res = func(3,-10)
    print(res)

    # 输出结果:
    # (<built-in function abs>, 3, -10)
    # func也是高阶函数 # abs是求绝对值的函数,用法:abs( 数字) # 函数返回多个值的时候,是以元祖形式返回的

    总结:

    只需满足以下一个条件即为高阶函数:

    1. 接收一个或多个函数作为输入

    2. return返回另一个函数

    递归函数:

    如果一个函数在其内部调用了它自己,这样的函数就是递归函数。 如:让10除以2,直到为0.

    a= 10
    def calc(n):
        n = int(n/2)
        print(n)
        if n >0:
            calc(n)   #在函数内部调用它自己,就会产生循环
    calc(a)
    
    # 输出结果:
    # 5
    # 2
    # 1
    # 0
    
    ## 而且,程序在结束退出的时候,是从内向外、一层一层逐渐结束的。
    测试:
    a= 10
    def calc(n):
        n = int(n/2)
        print(n)
        if n >0:   #这一步的代码运行分析:第1次print的n是5,由于5>0,n直接进入calc(n),由于calc(n)调用了它自己,就没有再走下面的print(‘程序退出测试:’,n)这一步,而是又返回上面去进行n=int(n/2)这几步。n是2和1的时候也是同样的道理。
            calc(n)
        print('程序退出测试:',n)  # 打印结果分析:最后一轮循环n的值是0,此时n==0不再进行calc(n),而是去运行下面的print(‘程序退出测试:’,n)这一步,此时最里面的这一层循环结束;然而上一步n==1时,程序是直接进入了if语句进行了calc(n),并没有进行下面的print语句,所以当最里面的n==0这层程序走完之后,n==1也要走完这个print语句。同理,n==2和5时也要依次走这个print语句。

    calc(a) # 输出结果: #
    5 # 2 # 1 # 0 # 程序退出测试: 0 # 程序退出测试: 1 # 程序退出测试: 2 # 程序退出测试: 5

    递归函数返回值: 

    在递归函数的外面得到返回值是最外层的函数return回来的,想要得到递归函数的返回值,需要在递归函数内部每次调用时都要有return值,只有这样最内层的return值才能通过一层层的return返回到最外层。它的书写方式是:

    if 条件成立:
        return 调用自己
    elsereturn 最里面的值 

    例如下面两个例子:

    例子1: 100除以2三次,函数外部得到返回值。
    
    a = 100
    def func(n,count):
        if count < 3:
            return func(n/2,count+1)
        else:
            return n
    result = func(a,0)
    print(result)
    
    # 输出结果:
    # 12.5
    
    例子2: 求3的阶乘,函数外部得到返回值。
    
    def f(n):
        if n > 1:
            return n*f(n-1)
        else:
            return n
    
    print(f(3))
    
    # 输出结果:
    # 6

    下面用流程图说明它们的返回值是怎么得到的:

    1. 3的阶乘:

     

    2. 100除以2三次:

  • 相关阅读:
    pdf 转图片,提取图片研究心得
    自己总结 C++ 代码规范
    Sublime Text 配置记录
    iOS控制器之基类设计
    SublimeText配置NodeJS代码提示
    YYCache设计思路及源码学习
    关于近期项目代码整理(iOS)
    iOS中iconfont(图标字体)的基本使用
    容器转场动画
    Xcode7 模拟器安装app (转)
  • 原文地址:https://www.cnblogs.com/neozheng/p/8350500.html
Copyright © 2020-2023  润新知