• day4-Python-函数进阶


    一、变量的作用域

    根据变量的作用范围把变量分为:局部变量和全局变量。

    def test(name,age,**kwargs):
        print(name)
        print(age)
        print(kwargs)
        test_1("test")
    def test_1(source):
        print("from %s"%source)
    test("bianbian",age=18,sex="girl",love="peng")
    

     结果:

    bianbian
    18
    {'sex': 'girl', 'love': 'peng'}
    from test
    

     test_1函数之后执行,没有问题;如果test_1函数之前执行会报错,因为test_1函数还没有被读到内存中,所以报错。

    def test(name,age,**kwargs):
        print(name)
        print(age)
        print(kwargs)
        test_1("test")
    test("bianbian",age=18,sex="girl",love="peng")
    def test_1(source):
        print("from %s"%source)
    结果:
    bianbian
    18
    {'sex': 'girl', 'love': 'peng'}
    Traceback (most recent call last):
      File "/Users/bianbian/PycharmProjects/test/test6.py", line 6, in <module>
        test("bianbian",age=18,sex="girl",love="peng")
      File "/Users/bianbian/PycharmProjects/test/test6.py", line 5, in test
        test_1("test")
    NameError: name 'test_1' is not defined
    

     1、局部变量

    指在局部生效,定义在函数体内的变量只能在函数里面生效,这个函数就是这个变量的作用域。

    def test(name):
        print("before change:", name)
        name="pengpeng"
        print("after change:", name)
    
    name="bian"
    print("------调用test------")
    test(name)
    print("------打印name------")
    print(name)
    

      结果:

    ------调用test------
    before change: bian
    after change: pengpeng #局部变量生效
    ------打印name------
    bian
    

    2、全局变量

    在整个程序中都生效的变量,在整个代码的顶层声明。

    love="pengpeng" # 定义全局变量
    def test_1():
        print("love", love)
    def test_2():
        love="shen"
        print("love", love)
    
    print("------test_1------")
    test_1()
    print("------test_2------")
    test_2()
    print("------打印love------")
    print("love", love)
    

      结果:

    ------test_1------
    love pengpeng #打印的是全局变量
    ------test_2------
    love shen #打印局部变量
    ------打印love------
    love pengpeng #打印全局变量
    

     全局变量的优先级是低于局部变量的,当函数体内没有局部变量,才会去找全局变量。

    3、修改变量作用域

    (1)函数里面修改全局变量

    现在global先声明一下全局变量,然后在函数中全局变量重新赋值

    love="pengpeng" # 定义全局变量
    def test_1():
        print("love", love)
    def test_2():
        global love
        love="shen"
        print("love", love)
    
    print("------test_1------")
    test_1()
    print("------test_2------")
    test_2()
    print("------打印love------")
    print("love", love)  

     结果:

    ------test_1------
    love pengpeng
    ------test_2------
    love shen
    ------打印love------
    love shen
    

    (2)只在函数里面声明全局变量

    love="pengpeng" # 定义全局变量
    def test_1():
        global love
        love="shen"
        print("love", love)
    
    print("------test_1------")
    test_1()
    print("------打印love------")
    print("love", love)
    

      结果:

    ------test_1------
    love shen
    ------打印love------
    love shen
    

      最好不要用global这个关键字,防止别人串改自己的代码。

    (3)修改列表

    love =['bianbian',"pengpeng"] # 定义一个列表
    def test_1():
        love[0]="shen"
        print(love)
    
    print("------test_1------")
    test_1()
    print("------打印love------")
    print(love)
    

      结果:

    ------test_1------
    ['shen', 'pengpeng'] #函数内的names输出
    ------打印love------
    ['shen', 'pengpeng'] #函数外的names输出
    

    列表love被当做在函数中全局变量,重新赋值了,是可以被修改的。

     (4)小节

    • 只有字符串和整数是不可以被修改的,如果修改,需要在函数里面声明global。
    • 但是复杂的数据类型,像列表(list)、字典(dict)、集合(set),包括我们后面即将要学的类(class)都是可以修改的。

    3、作用域小结

    • 在子程序(函数)中定义的变量称为局部变量,在程序一开始定义的变量称为全局变量。
    • 全局变量的作用域是整个程序,局部变量的作用域是定义该变量的子程序(函数)。
    • 当全局变量和局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其他地方,全局变量起作用。

    二、递归

    1、定义

    一个函数在内部调用自身,这个函数被称为递归函数。

    def test(n):
        print(n)
        if int(n/2) == 0:#结束符
            return n
        return test(int(n/2)) #调用函数自身
    a = test(10)
    

      结果:

    10
    5
    2
    1
    

    根据代码,最后一层,一定需要一个结束符,来结束。

    def test(n):
        if n == 0:
            return n
        return n+test(n-1)
    n=test(100)
    print(n)
    结果:
    5050
    

    test(n-1)返回的是(n-1)+test(n-2)......

    2、递归特性总结

    • 必须要有一个明确的结束条件。
    • 每次进入更深一层的递归时,问题规模相比上次递归都应该少(问题规模:比如你第1次传进的是10,第2次递归应该是9...依次越来越少,不能越来越多)。
    • 递归的效率不高,递归层次过多会导致内存溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈贞,每当函数返回,栈就会减一层栈贞。由于栈的大小不是无限的,所以递归的次数过多,会导致栈溢出)。

    第3点关于这个内存溢出说明:栈不是无限的,它是有限的,过多会导致内存溢出。如图:

    三、高阶函数

    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,高阶函数功能就是:把函数本身当做一个参数,传到另一个函数中,然后在这个函数中做处理。

      

  • 相关阅读:
    访问虚拟机
    w3school JavaScript 简介
    蘑菇街2016研发工程师在线编程题
    乐视2017暑期实习生笔试题(二)
    今日头条2017后端工程师实习生笔试题
    c# 读取 excel文件内容,写入txt文档
    处理字符串
    XML获取节点信息值
    SVN仓库目录结构
    sql 知识点
  • 原文地址:https://www.cnblogs.com/bianfengjie/p/10742029.html
Copyright © 2020-2023  润新知