• 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()
    #
  • 相关阅读:
    python爬虫之趟雷
    python附录-builtins.py模块str类源码(含str官方文档链接)
    python-基础学习篇(一)
    pycharm和webstorm永久激活方法
    计算机网络基础概述
    计算机基础
    B/S和C/S架构简单理解
    认识HTML中文本、图片、链接标签和路径
    结对开发
    全国疫情可视化地图 (一)
  • 原文地址:https://www.cnblogs.com/frx9527/p/python_11.html
Copyright © 2020-2023  润新知