zoukankan      html  css  js  c++  java
  • 第十二篇 Python函数之全局变量&局部变量&递归函数

    全局变量:在定义的时候,顶头写的,没有任何缩进的变量就是全局变量。

    全局变量的特点:在当前文件里的任何地方都可以进行调用

    局部变量:在子程序里定义的变量,就是局部变量。

    子程序:比如.py文件里,写的函数就是个子程序。而这个函数里定义的变量就是局部变量

    示例:全局变量

    # 全局变量
    name='alex'  
    
    def change_name():
        print('change_name',name)  # 调用了全局变量
    
    change_name()
    # 结果
    change_name alex
    
    print(name)    #调的是全局变量
    # 结果
    alex

    示例:函数体内定义局部变量

    # 全局变量:全局作用域
    name='alex'
    
    def change_name():
        name='帅呆了'  # 局部变量:局部作用域
        print('change_name',name)  # 先在自己的子程序里找,调用了局部变量
    
    # 举个生活中的例子,刚起床找手机,肯定现在自己卧室(函数)找,自己卧室找不到,才可能会到卧室(函数之外)之外去找。
    # 所以,很好的理解,就是优先内部,然后外部;局部变量只能该函数自己使用(私心重),全局变量就比较大方,谁需要就可以拿去用
    
    change_name()       
    # 结果
    change_name 帅呆了
    
    print(name)    #调的是全局变量
    # 结果
    alex

    示例:函数体内声明全局变量

    # 全局变量
    name='alex'
    
    def change_name():
        global name     # 函数体内声明了全局变量
        name='帅呆了'    # 函数体内修改了全局变量的值
        print('change_name',name)  # 调用了全局变量
    
    change_name()
    # 结果
    change_name 帅呆了
    
    print(name)    #调的是全局变量,但是全局变量的值已经被修改
    # 结果
    帅呆了

    更好的示例

    如果函数的内容无global关键字,优先读取局部变量;如果没有局部变量,只能读取全局变量,无法对全局变量重新赋值,但于可变类型,是可以对内部元素进行操作

    如果函数的内容有global关键字,函数内的变量就是全面局变量,可以读取,可以赋值

    name = "桃花李"
    
    def yangjian():
        global name # 已经声明,NAME就是全局的的那个变量
        print('我要', name)
        name = "小东北"  # 修改 全局的变量
        print('我要', name)
    
    def qupengfei():
        name = ""
        print('我要搞', name)
    
    yangjian()
    qupengfei()
    
    #结果
    我要 桃花李
    我要 小东北
    我要搞 基

    总结

    全局变量变量名大写
    局部变量变量名小写
    下面的示例为了说明全局变量和局部变量的关系,都用的是大写。

    # 如果函数的内容无global关键字:
    # - 有声明局部变量
    NAME = ["产品经理","廖波湿"] def qupengfei(): NAME = "自己" print('我要搞', NAME) qupengfei() # - 无声明局部变量 NAME = ["产品经理","廖波湿"] def qupengfei(): NAME.append('XXOO') print('我要搞', NAME) qupengfei() # 如果函数的内容有global关键字 # - 有声明局部变量 NAME = ["产品经理","廖波湿"] def qupengfei(): global NAME NAME = "自己" print('我要搞', NAME) qupengfei() # 错误示例, 全部变量放在了局部变量的下面,是不行的;所以,如果要什么全局变量,就尽量往前放。 NAME = ["产品经理","廖波湿"] def qupengfei(): NAME = "自己" global NAME print('我要搞', NAME) qupengfei() # - 无声明局部变量 NAME = ["产品经理","廖波湿"] def qupengfei(): global NAME NAME = ["阿毛"] NAME.append('XXOO') print('我要搞', NAME) qupengfei()

    函数里也可以嵌套函数,执行顺序如下图所示

      

    name='海风'
    def huangwei():
        name = "黄伟"
        print(name)
        def liuyang():
            name = "刘洋"
            print(name)
            def nulige():
                name = '炉指花'
                print(name)
            print(name)
            nulige()
        liuyang()
        print(name)
    
    huangwei()
    # 结果
    黄伟
    刘洋
    刘洋
    炉指花
    黄伟

    name = "刚娘"
    
    def weihou():
        name = "陈卓"
        def weiweihou():
            global name   # global,声明的是全局变量,
            name = "冷静"  # 此处修改的是最外层的全局变量,而不是它上一级同名变量
        weiweihou()
        print(name)
    print(name)
    weihou()
    print(name)
    
    #结果
    刚娘
    陈卓
    冷静

    name = "刚娘"
    
    def weihou():
        name = "陈卓"
        def weiweihou():
            nonlocal name   # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
            name = "冷静"
        weiweihou()
        print(name)
    
    print(name)
    weihou()
    print(name)
    
    # 结果
    刚娘
    冷静
    刚娘

     前向引用(野路子好记,别名风湿理论):函数即变量

    def foo():
        print('from foo')
        bar()
    
    def bar():
        print('from bar')
    
    foo()
    # 结果
    from foo
    from bar
    def foo():
        print('from foo')
        bar()
    
    foo()
    # 结果
    程序报错,因为没有定义bar()
    def foo():
        print('from foo')
        bar()
    
    foo()
    
    def bar():
        print('from bar')
    
    # 结果
    报错,即使定义了bar(),但是他放在了foo()调用的后面,也不会执行

    # 用前向引用解释函数嵌套的调用

    name='海风' def huangwei(): name = "黄伟" print(name) def liuyang(): name = "刘洋" print(name) def nulige(): name = '炉指花' print(name) print(name) nulige() liuyang() print(name) print(name) huangwei() print(name) # 结果 黄伟 刘洋 刘洋 炉指花 黄伟 海风

    函数递归

    递归就好比你去问A腾达大厦怎么走?A说我不知道,我去问问B,B说完我也不知道,我去问问C,然后C又去问D,D说我知道,告诉了C,C又告诉了B,B告诉了A,A把最后的结果返回给了你。

    递归特性:

    1. 必须有一个明确的结束条件

    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

    堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

    尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

    示例:

    递归函数内部,有自己调用自己,就会形成一个循环,一直循环下去, 最后报错

     

    def calc(n):
        print(n)
        calc(n)
    
    calc(10)
    
    #结果
    10
    10
    ...10
    RecursionError: maximum recursion depth exceeded while calling a Python object
    def calc(n):
        print(n)
        if int(n/2) ==0:
            return n
        return calc(int(n/2))
     
    calc(10)
     
    输出:
    10
    5
    2
    1
    # 以问路的生活实例来解释递归函数
    import time
    
    # 问路,得先有问的人,需要定义一个列表
    person_list=['alex','wupeiqi','yuanhao','linhaifeng''sb’]
    # 
    def ask_way(person_list):
        print('-'*60)
        if len(person_list) == 0:   # 该条件表示该问的人都问完了,没人知道路
            return '没人知道'       # 终止
        person=person_list.pop(0)    # 一次弹出一个人
        if person == 'linhaifeng':   # 该条件表示这个人知道路
            return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
        print('hi 美男[%s],敢问路在何方' %person)
        print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' %(person,person_list))
        time.sleep(3)
        res=ask_way(person_list)
        print('%s问的结果是: %res' %(person,res))
        return res
    
    res=ask_way(person_list)
    print(res)
    
    # 结果
    ------------------------------------------------------------
    hi 美男[alex],敢问路在何方
    alex回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['wupeiqi', 'yuanhao', 'linhaifeng', 'zsc']...
    ------------------------------------------------------------
    hi 美男[wupeiqi],敢问路在何方
    wupeiqi回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['yuanhao', 'linhaifeng', 'zsc']...
    ------------------------------------------------------------
    hi 美男[yuanhao],敢问路在何方
    yuanhao回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['linhaifeng', 'zsc']...
    ------------------------------------------------------------
    yuanhao问的结果是: 'linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是'es
    wupeiqi问的结果是: 'linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是'es
    alex问的结果是: 'linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是'es
    linhaieng说:我知道,老男孩就在沙河汇德商厦,下地铁就是
  • 相关阅读:
    JAVA URI URL 区别
    超轻量级DI容器框架Google Guice与Spring框架的区别教程详解及其demo代码片段分享
    开源框架:Apache的DBUtils框架
    java url openConnection get post 请求
    java 使用jxl poi 操作excel
    如何用Curl 来post xml 数据
    Linux Shell脚本编程--Linux特殊符号大全
    linux查看各服务状态以及开启和关闭
    eclipse中点不出来提示
    cocos2dx切换场景
  • 原文地址:https://www.cnblogs.com/victorm/p/9126380.html
Copyright © 2011-2022 走看看