• 小白学 Python(17):基础数据类型(函数)(下)


    人生苦短,我选Python

    前文传送门

    小白学 Python(1):开篇

    小白学 Python(2):基础数据类型(上)

    小白学 Python(3):基础数据类型(下)

    小白学 Python(4):变量基础操作

    小白学 Python(5):基础运算符(上)

    小白学 Python(6):基础运算符(下)

    小白学 Python(7):基础流程控制(上)

    小白学 Python(8):基础流程控制(下)

    小白学 Python(9):基础数据结构(列表)(上)

    小白学 Python(10):基础数据结构(列表)(下)

    小白学 Python(11):基础数据结构(元组)

    小白学 Python(12):基础数据结构(字典)(上)

    小白学 Python(13):基础数据结构(字典)(下)

    小白学 Python(14):基础数据结构(集合)(上)

    小白学 Python(15):基础数据结构(集合)(下)

    小白学 Python(16):基础数据类型(函数)(上)

    变量作用域

    变量的作用域是指在程序中命名的变量产生想过的范围。

    没看懂?没关系,我们写个示例慢慢品。

    a = 0
    
    def print_1():
        a = 1
        print('a =', a)
    
        def print_2():
            a = 2
            print('a =', a)
    
    print_1()
    

    显示结果如下:

    a = 1
    

    在上面的示例中, a 我们进行了三次赋值,但是注意,这里并不是赋值覆盖,而是每次赋值时作用域不同。

    第一次赋值 a 是在最外面,这个称为全局变量,意思是它的作用域是全局的,我们在全局任何地方使用 a ,都能获得这个值。

    第二次赋值, a 是在 print_1() 这个函数中,我们调用了 print_1() 这个函数,所以这里的赋值会生效。

    第三次赋值是在 print_2() 这个函数中,我们并未调用这个函数,所以这里 a 的赋值并不会生效。

    比如我们可以这么打印:

    a = 0
    
    def print_1():
        a = 1
        print('a =', a)
    
        def print_2():
            a = 2
            print('a =', a)
    
    
    print('a =', a)
    

    打印结果如下:

    a = 0
    

    这时我们就将这个全局变量打印出来了。

    第二个和第三个在方法内的 a 就成了局部变量,这两个 a 都是只在当前的函数中生效,出了这个函数就不生效了。

    如果我们将局部变量中的的赋值注释掉,那么在函数中是否能取到全局变量的值?

    答案当然是肯定的,我们试试看:

    a = 0
    
    def print_1():
        # a = 1
        print('a =', a)
    
        def print_2():
            a = 2
            print('a =', a)
    
    print_1()
    

    打印结果如下:

    a = 0
    

    我们还可以再做一点改变,在函数 print_1() 中调用函数 print_2() ,如下:

    a = 0
    
    def print_1():
        # a = 1
        print('a1 =', a)
    
        def print_2():
            a = 2
            print('a2 =', a)
    
        print_2()
    
    print('a3 =', a)
    print_1()
    

    打印结果如下:

    a3 = 0
    a1 = 0
    a2 = 2
    

    此示例添加 a1 、 a2 、 a3 仅为打印后方便识别,并非这是三个变量。

    注意: 内层函数的变量作用域仅在内层函数中,并不会覆盖到外层函数。

    匿名函数

    是的,你没看错,函数是可以不命名的。

    当我们需要使用匿名函数的时候,可以使用 lambda 关键字来声明匿名函数。

    • lambda 只是一个表达式,函数体比 def 简单很多。
    • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
    • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。

    语法:

    函数对象名 = lambda 形参:表达式
    

    我们还是写一个简单的匿名函数大家体会一下:

    add = lambda x,y: x   y
    
    print(add(1, 2))
    

    打印结果如下:

    3
    

    这里是实现了我们上一篇文章中最简单的加法,如果写一个稍微复杂一点,比如说加上逻辑判断的:

    max_num = lambda x,y: x if x >= y else y
    
    print(max_num(5, 9))
    

    打印结果如下:

    9
    

    建议: 当函数比较复杂的时候,不建议使用匿名函数,因为它只能是一行,写起来不好写的同时还不好阅读,结构晦涩难懂,如果进行复杂的业务逻辑,匿名函数能让写的人怀疑人生,读的人生不如死。真爱生命,请远离匿名函数。

    递归函数

    一个函数是可以调用另一个函数的,如果这个函数调用自己的话,那么这个就叫递归函数。

    现在我们如果要求 n 的阶乘:

    千万别告我你不知道什么阶乘,可能你需要回去问下你的初中数学老师。

    n! = 1 * 2 * 3 * ... * n

    看懂了哇,想想看代码怎么写。

    想不出来还是看我写的吧:

    def factorial(n):
        if n == 1:
            return 1
        return n * factorial(n - 1)
    
    print('10的阶乘为:', factorial(10))
    

    打印结果:

    10的阶乘为: 3628800
    

    希望各位同学一定要自己动手敲代码。

    示例代码

    本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。

    示例代码-Github

    示例代码-Gitee

    您的扫码关注,是对小编坚持原创的最大鼓励:)
  • 相关阅读:
    上传文件(一)
    momentjs
    asp.net中session的原理及应用
    聊天程序(基于Socket、Thread)
    接口与抽象类
    asp.net 发送邮件
    Web.Config文件详解
    Apache Sqoop
    HBase 数据模型(Data Model)
    HBase框架学习之路
  • 原文地址:https://www.cnblogs.com/createwell/p/12185746.html
Copyright © 2020-2023  润新知