美文网首页
PYTHON源码之基本对象(int string list di

PYTHON源码之基本对象(int string list di

作者: 荒原葱郁 | 来源:发表于2017-08-11 19:33 被阅读18次

    前面分析了python内置类型的组成结构,今天来具体说说python基本内置类型的存储问题。
    先谈谈int
    python内部的int分为小整数和大整数,小整数[-5,257),大整数即为其他的一些整数。
    这样分的理由是一般来说我们编程,循环呀啥的,小整数出现的情况比较多,至于为啥是从-5开始到257,这个估计是python作者的经验了。
    小整数对象的存储数组为:

    #define NSMALLNEGINTS 5
    #define NSMALLPOSINTS  257
    static PyIntObject  * small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
    

    small_ints被高大上的称之为小整数“内存池”,从python一运行,小整数在内存里面的位置就固定了,而且顺序也定下来,2在1的后一个,2的后面是3,即-5,-4,-3,-2.....。那么大整数呢?在python里面定义一个大整数,也不是定义一个就申请一下内存,开辟一个空间。大整数有大整数的内存池:

    struct _intblock{
      struct _intblock *next;
      PyIntPbject objects[N_INTOBJECTS];
    }
    

    上面只是存储大整数的一个块,很多块连起来,就成了一个单向链表。
    假设系统刚刚开始,我们还只有一个这样的块,从感觉上来讲,PyIntPbject objects[N_INTOBJECTS];肯定是存放具体对象的地方,也和小整数一样连续存放,一个萝卜一个坑?来个1亿几万亿怎么办?所以不是这样的,在这里python的设计者用了一个奇妙的方法。


    大整数对象的链表形式.png

    原来,是拿着数组的空间当链表用,ob_type经过强制类型转化后充当了next指针的作用。
    屡一下流程
    申请一个整数,比如1000;
    取出头指针(free_list)指向的元素,填充1000,头指针后移。
    删除一个整数;
    把删除的整数元素作为头结点加入到free_list链表当中。

    string的字符存储方式和int小整数的一样,都是一个指针数组来指示位置的,但是字符串的不一样,有inner和非inner的方式,inner方式的“abc”和“abc”的地址是一样的,非inner方式,其内存地址不一样。

    list和dict的和int与string有些不一样,他们是实时申请的,但在释放时,只释放对象里面动态内存的那一部分(即对象的内容),对象本身是没有被释放的,把他的地址存在一个数组中,这个数组的实际作为一个栈,若有申请,则往这个数组里面取栈顶地址然后初始化即可。

    python源码基本的对象介绍到这里,下一章为pyc与PyCodeObject。

    相关文章

      网友评论

          本文标题:PYTHON源码之基本对象(int string list di

          本文链接:https://www.haomeiwen.com/subject/vuurrxtx.html