zoukankan      html  css  js  c++  java
  • Python函数作用域名字空间,locals的原理。

    最近在回看《Python学习笔记》看到函数这一章节,书中P153页。

    书中介绍了函数的每次调用,都会新建栈帧,用于局部变量和执行过程的存储。

    等执行结束,栈帧内存被回收,同时释放相关对象。

    以字典实现的名字空间,虽然灵活,但存在访问效率低下等问题。这对于使用频率较低的模块名字空间尚可,可对于有性能要求的函数调用,显然就是瓶颈所在。

    为此,解释器划出专门的内存空间,用效率最快的数组代替字典。在函数指令执行前,先将包含参数在内的所有局部变量,以及要使用的外部变量复制(指针)到该数组。

    基于作用域不同,此内存区域可简单分为两部分:FAST和DEREF

    如此,操作指令只需要索引既可理解读取或存储目标对象,这远比哈希查找过程高效很多。从dis可以看出来,load读取操作的都是索引。

    空间名字

    那locals函数返回的东西是哪里来的,locals函数产生的字典是按需延迟创建,并从FAST区域复制相关信息得来的。

    def test():
        x = 100
        locals()['x'] = 999
    
        print('fast.x =', x)
        print('local.x =', locals()['x'])
    
    
    test()
    

      输出

    fast.x = 100
    local.x = 100

    从输出就可以看出来,locals并不能改变函数局部作用域的命名空间,这个一个单线的操作,每次都会从函数的命名空间的元祖生成一个字典,

    可能是为了对应globals吧,也可能为了格式的统一显式。

    这个Python的底层还真的有意思。

  • 相关阅读:
    python初识面向对象
    python装饰器
    python递归函数及二分法查找
    python内置函数及匿名函数
    生成器和生成器函数以及各种推导式
    第一类对象 函数名 变量名
    初识函数
    文件操作
    基本数据类型补充 深浅拷贝
    Python小程序练习及认识小数据池和编码
  • 原文地址:https://www.cnblogs.com/sidianok/p/14340065.html
Copyright © 2011-2022 走看看