美文网首页
Python之路9:基础函数

Python之路9:基础函数

作者: 缘小泽 | 来源:发表于2018-04-04 22:45 被阅读0次

    函数

    函数是将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需要调用函数名即可

    注:函数在没有执行前,内部代码不执行

    特性:
    减少重复的代码
    使程序变得可扩展
    使程序变得易维护

    实例:

    def hel():   # 定义函数名
        print('Hello World!') # 函数内的内容
    hel()  # 调用函数
    
    # 执行结果
    Hello World!
    

    函数的参数

    • 形参变量

    只有在被调用是才分配内存单元,形参只在函数内部有效,函数调用结束后返回主程序后则不在调用此形参变量

    • 实参

    可以是常亮,变量,表达式,函数等,无论实参是何种类型的变量,在进行函数调用时,它们都必须有特定的值,以便把这些值传给形参

    实例:

    def calc(x, y):  # x,y 为形参
        res = x**y
        return res
    s = calc(2, 5)  # 2,5 是需要传送的实参数据
    print(s)
    
    # 执行结果
    32
    

    关键参数

    实例:

    def stu_register(name, age, country, course='CN'): #如传入的某个参数值是一样的,就可以在定义函数是指定参数值是多少,且指定的变量值的后面不允许有需要传入值的变量
        print('注册学生信息'.center(10, '-'))
        print('姓名:', name)
        print('age:', age)
        print('国籍:', course)
        print('课程:', country)
    
    stu_register('zevin', 22, 'python') #此处传入字符串需要严格对应参数内的变量
    
    # 执行结果
    --注册学生信息--
    姓名: zevin
    age: 22
    国籍: CN
    课程: python
    
    # 也可以在传入参数值时指定变量
    def stu_register(name, age, country, course):
        print('注册学生信息'.center(10, '-'))
        print('姓名:', name)
        print('age:', age)
        print('国籍:', course)
        print('课程:', country)
    
    stu_register('zevin',23, course='JP', country='python') #若没有指定变量的参数,需要按照函数格式传入值
    
    # 执行结果
    --注册学生信息--
    姓名: zevin
    age: 23
    国籍:JP
    课程: python
    

    非固定参数

    若函数中有些定义的变量需要传入多个参数,就可以使用非固定参数
    用法:*变量, 在变量前加个 * 星号
    实例:

    # 变量前一个 * 星号
    def stu_register(name, age, *args): # *args 会把多传入的值变成一个元祖形式
        print(name, age, args)
    stu_register('zevin', 22)
    # 执行结果
    # zevin 22 () #后面这个()就是args的值,因为没有传入值,所以为空
    
    stu_register('zevin', 22, 'CN', 'JP')
    # 执行结果
    # zevin 22 ('CN', 'JP') # 最后多传入的值变成元祖
    
    # 变量前两个 * 星号
    def stu_register(name, age, *args,  **kwargs): # **kwargs会把多传入的值变成一个字典形式
        print(name, age, args, kwargs)
    stu_register('zeivn', 22, 'CN', 'JP', sex='abc', pro=123)
    # 执行结果
    # zeivn 22 ('CN', 'JP') {'sex': 'abc', 'pro': 123}
    

    函数的返回值

    函数外部的代码想要获取函数执行的结果,就可以在函数内用 return 语句把结果返回,不加默认返回 None
    注意:
    函数在执行过程中只要遇到 return 语句,就会停止执行并返回结果

    实例:

    def sun(x, y):
        if x > y:
            x*y
        else:
            x**y
    fo = sun(5, 6)
    print(fo)
    # 执行结果为 None
    
    def sun(x, y):
        if x > y:
            return x*y
        else:
           return x**y
    fo = sun(5, 6)
    print(fo)
    # 执行结果为 15625
    

    局部变量

    在函数中定义的变量称为局部变量,在程序一开始定义的变量称为全局变量
    当全局变量和局部变量同名时,在定义局部变量的函数内,局部变量起作用,在其他地方全局变量起作用

    实例:

    name = 'anv'  # 在程序开始定义 name = anv
    def change_name():
        name = 'dsf'    # 在函数内定义 name = dsf
        print('函数内name为:', name, id(name))   #在函数内打印name
    change_name()
    print('函数外name为:', name, id(name))  #在函数外打印name
    
    # 执行结果
    函数内name为: dsf  140357042555120
    函数外name为: anv  140357042555064
    
    
    # 要想在函数内修改全局变量,需要用参数 global 修改
    name = 'anv'  # 在程序开始定义 name = anv
    def change_name():
        global name  # global声明需要修改的变量,建议不要更改全局变量
        name = 'dsf'    # 在函数内修改为 name = dsf
        print('函数内name为:', name, id(name))   #在函数内打印name
    change_name()
    print('函数外name为:', name, id(name))  #在函数外打印name
    
    # 执行结果
    函数内name为: dsf 140056539031792
    函数外name为: dsf 140056539031792
    

    嵌套函数

    函数内部可以再次定义函数,执行需要调用

    # 实例 1
    age = 18      # 全局定义 age = 18
    def func1():
        age = 73  # 函数内定义 age = 73
        print('func1:', age)
        def func2():
            age = 84
            print('func2:', age)
    func1()   # 调用 func1()
    
    # 执行结果,未调用 func2() 所有以输出 func1 的值
    func1:73
    # 实例 2
    age = 18      # 全局定义 age = 18
    def func1():
        age = 73  # 函数内定义 age = 73
        print('func1:', age)
        def func2():
            age = 84
            print('func2:', age)
        func2()  # 调用 func2()
    func1()   # 调用 func1()
    
    # 执行结果
    func1:73
    func2:84
    # 实例 3
    age = 18      # 全局定义 age = 18
    def func1(): # 函数内定义 age = 73
        print('func1:', age)  # 此age 直接调用的是全局变量 age 值
        def func2():
            print('func2:', age) 
        func2()  # 调用 func2()
    func1()   # 调用 func1()
    
    # 执行结果
    func1: 18
    func2: 18
    # 实例 4
    age = 18      # 全局定义 age = 18
    def func1(): # 函数内定义 age = 73
        age = 73   # 函数内定义 age = 73
        print('func1:', age)
        def func2():
            print('func2:', age) # func2()函数内的age从上一层父级获取 age 值,如果上一层 age未赋值,则在往上一层查找
        func2()  # 调用 func2()
    func1()   # 调用 func1()
    
    # 执行结果
    func1: 73
    func2: 73
    

    匿名函数

    把多行语句提供成一行,不需要函数名,支持三元运算,主要是和其他方式搭配运算

    # 如以下代码
    def calc(x, y):
        return x*y
    
    print(calc(2, 5))
    # 执行结果
    10
    
    # 换成匿名函数
    calc = lambda x, y: x*y
    print(calc(2, 5))
    # 执行结果
    10
    
    # 还可以进行三元运算
    calc = lambda x, y: x*y if x < y else x/y
    print(calc(16, 8))
    # 执行结果
    2.0
    
    # 匿名函数主要搭配其他函数使用
    # map(func, list) 是将后面列表中的每一个值交给前面的函数去执行一边
    res = map(lambda x: x*2, [1, 5, 6, 7]) #将后面的列表内每一个值交给前面的 lamba 函数进行自乘
    for line in res:
        print(line)
    # 执行结果
    2
    10
    12
    14
    

    高阶函数

    变量可以指向函数,函数的参数能接受变量,那么一个函数可以接受另一个函数作为参数,这种就是 高阶函数

    • 接受一个或多个函数作为输入
    • return 返回另外一个函数
    def calc(x, y):
        return x*y
    
    def func(x):
        return x+x
    
    print(calc(func(4), 5)) # 将func(4)返回的函数结果作为calc函数的参数
    
    # 执行结果
    40
    

    作用域

    Python 中作用域,变量会由内向外查找,先在自己作用域查找,如果没有就再去上级查找,依次向上,直到找不到就报错

    # 先看这段代码
    name = 'li'
    def f1():
        print(name)
    def f2():
        name = 'al'
      return f1
    
    res = f2()
    res()
    # 输出:li
    
    # 分析上面的代码,先执行f2()函数,而f2()执行结果返回的 f1 的内存地址,所以res=f1,在后面执行res()就等于执行f1(),而执行f1()时和执行f2()没有关系,f1()内并没有定义变量name的值,所以f1()就上级查找name变量的值,所有 name = "li" 就是和 f1()为一个作用域链,最后返回的结果为 li
    
    # 最后看这段代码
    name = 'li'
    def f1():
        print(name)
    def f2():
        name = 'al'
        f1()
    f2()
    # 输出: li
    
    # 此段代码和上面的基本是一样的,执行f2()后调用了f1(),最后的结果为f1()向上级查找name变量值,最后返回name变量值
    # 在函数未执行之前,作用域已经形成了,而作用域链也生成了
    

    作用域的查找顺序:
    LEGB:

    • locals: 函数内部的名称空间,包括局部变量和形参
    • enclosing: 外部嵌套函数的名称空间
    • globals: 全局变量,函数定义所在模块的名称空间
    • builtins 内置模块的名称空间

    递归

    在函数内部可以调用其他函数,如果一个函数在内部调用自己本身时,这个函数就一个递归函数

    递归特性:

    • 必须要有一个明确的结束条件
    • 每次进入更深一层递归时,问题规模应该比上级递归减少
    • 递归的效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)
    # 递归的用法
    # 计算 介乘,
    def num(n):
        if n == 1:
            return 1
      return n * num(n - 1)
    print(num(5))
    # 输出:120
    

    相关文章

      网友评论

          本文标题:Python之路9:基础函数

          本文链接:https://www.haomeiwen.com/subject/afnlhftx.html