zoukankan      html  css  js  c++  java
  • python基础11_函数作用域_global_递归

    看到了一个16进制转换的小知识点,就验证了一下运行结果.

    #!/usr/bin/env python
    # coding:utf-8
    
    # 看到了16进制转换的问题。顺便验证一下。
    a = 255
    b = 1001
    print(hex(a), hex(b))
    
    c = 0xff
    d = 0x3e9
    print(int(c),int(d))

    继续往前走, 学习一下global关键字

    参考: http://www.pythonav.com/special/100-18.html

    注意: global 是不安全的,尽量少用。建议使用函数的传参代替它。

    #!/usr/bin/env python
    # coding:utf-8
    
    name = "tom"  # 全局作用域
    
    
    def chg_name():
        global name # 有关键字
        name = "jerry"  # 修改了全局的变量
        age = 38 #  局部作用域
        print('change_name', name,age)
    
    # 如果函数内部没有global关键字,只能读取全局变量,无法对全局变量重新赋值.
    # 但是对于可变类型,依然可对内部元素进行操作.
    
    names =['toma','abc','kaka']
    
    def qiuxin():
        names.append('meixi')
        print(names)
    
    qiuxin()
    
    
    def change_name():
        # name = "Anna"  #
        age = 18 #  局部作用域
        print(name,age)
    
    
    # def change_name2():
    #     name = "Anna"  #
    #     age = 18 #  局部作用域
    #     global name # 关键字需要放在局部的最上面.
    #     print(name,age)
    
    
    change_name()
    chg_name()
    print(name)
    
    ### 规则: 全局变量名全部大写, 局部变量小写
    # 命名空间 有三种
    # 内置命名空间 —— python解释器
        # 就是python解释器一启动就可以使用的名字存储在内置命名空间中
        # 内置的名字在启动解释器的时候被加载进内存里
    # 全局命名空间 —— 我们写的代码但不是函数中的代码
        # 是在程序从上到下被执行的过程中依次加载进内存的
        # 放置了我们设置的所有变量名和函数名
    # 局部命名空间 —— 函数
        # 就是函数内部定义的名字
        # 当调用函数的时候 才会产生这个名称空间 随着函数执行的结束 这个命名空间就又消失了
    
    # 在局部:可以使用全局、内置命名空间中的名字
    # 在全局:可以使用内置命名空间中的名字,但是不能用局部中使用
    # 在内置:不能使用局部和全局的名字的

    验证一下函数以及变量的作用域:

    #!/usr/bin/env python
    # coding:utf-8
    
    # 函数的嵌套    
    # 函数的嵌套定义 
    # 内部函数可以使用外部函数的变量 
    def huangwei():
        name = "黄伟"
        print(name)
    
        def liuyang():
            name = "刘洋"
            print(name)
    
            def nuli():
                name = "沪上"
                print(name)
    
            print(name)
            nuli()
    
        liuyang()
        print(name)
    
    
    huangwei()
    
    ## 以上代码的执行顺序,可以通过断点调试来验证。
    
    
    ename = "tom"
    
    
    def wei():
        ename = "U"
    
        def suo():
            global ename  # 这里实际上拿到的是 tom
            ename = 'SA'
    
        suo()
        print(ename)  # 这里实际上是32行的U
    
    
    print(ename)
    wei()
    print(ename)

    与global作为对比的,有另一个关键字 nonlocal

    #!/usr/bin/env python
    # coding:utf-8
    
    ename = "tom"
    
    
    def wei():
        ename = "U"
    
        def suo():
            nonlocal ename  # 这回拿到的是上一级的
            ename = 'SA'
    
        suo()
        print(ename)  # 这里实际上是32行的U
    
    
    print(ename)
    wei()
    print(ename)  
    # nonlocal 只能用于局部变量 找上层中离当前函数最近一层的局部变量
    # 声明了nonlocal的内部函数的变量修改会影响到 离当前函数最近一层的局部变量
    # 对全局无效
    # 对局部 也只是对 最近的 一层 有影响
    

     函数即变量 

    来自:  http://www.cnblogs.com/linhaifeng/articles/6113086.html#label1

    函数名 作为函数的返回值 或 参数

    # def func():
    #     print(123)
    #
    # # func()  #函数名就是内存地址
    # func2 = func  #函数名可以赋值
    # func2()
    #
    # l = [func,func2] #函数名可以作为容器类型的元素
    # print(l)
    # for i in l:
    #     i()
    
    def func():
        print(123)
    
    def wahaha(f):
        f()
        return f           #函数名可以作为函数的返回值
    
    qqxing = wahaha(func)   # 函数名可以作为函数的参数
    qqxing()

    递归: 

    #!/usr/bin/env python
    # coding:utf-8
    
    ### 递归好比问路
    # 递归效率不高,
    
    def calc(n):
        print(n)
        if int(n / 2) == 0:
            return n
        res = calc(int(n / 2))
        return res
    
    calc(10)

     关于问路的举例:

    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    import time
    
    person_list=['alex','wupeiqi','yuanhao','linhaifeng']
    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)

    直接cp了老师的总结: 其实想要掌握,还是要多练,多练,多练, 还是多练.

    递归特性:

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

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

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

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

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

    闭包:

    https://www.cnblogs.com/Eva-J/articles/7156261.html#_label5

    # 闭包:嵌套函数,内部函数调用外部函数的变量
    def outer():
        a = 1
        def inner():
            print(a)
        # __closure__ 可以用来判断闭包
        # print(inner.__closure__)  # 打印 cell at ... 则表明它是一个闭包
        return inner  # 返回内部函数的内存地址,因为此函数用到了外部函数的变量,所以外部函数的变量也不会因函数的调用结束而消失
    inn = outer()
    inn()
    
    from urllib.request import urlopen
    # ret = urlopen('http://www.xiaohua100.cn/index.html').read()
    # print(ret)
    
    # def get_url():
    #     url = 'http://www.xiaohua100.cn/index.html'
    #     ret = urlopen(url).read()
    #     print(ret)
    #
    # get_url()
    
    # 闭包的简单示例:
    # def get_url():
    #     url = 'http://www.xiaohua100.cn/index.html'
    #     def get():
    #         ret = urlopen(url).read()
    #         print(ret)
    #     return get    # 得到 url 结果
    #
    # get_func = get_url()   # 将结果赋给变量,保存下来。
    # get_func()
    #
  • 相关阅读:
    Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.
    旋转二维数组
    replace empty char with new string,unsafe method和native implementation的性能比较
    判断一字符串是否可以另一字符串重新排列而成
    移除重复字符的几个算法简单比较
    也来纠结一下字符串翻转
    判断重复字符存在:更有意义一点
    程序员常去网站汇总
    sublime
    针对程序集 'SqlServerTime' 的 ALTER ASSEMBLY 失败,因为程序集 'SqlServerTime' 未获授权(PERMISSION_SET = EXTERNAL_ACCESS)
  • 原文地址:https://www.cnblogs.com/frx9527/p/python_11.html
Copyright © 2011-2022 走看看