zoukankan      html  css  js  c++  java
  • python常见对象的结构

    1 整数对象PyIntObject

    整数对象是固定大小的Python对象,内部只有一个ob_ival保存实际的整数值。

    typedef struct {
        PyObject_HEAD
        long ob_ival;
    } PyIntObject;

    2 字符串对象PyStringObject

    Python的字符串对象是一个不可变对象,任何改变字符串字面值的操作都是重新创建一个新的字符串。

    字符串对象在Python中用PyStringObject表示,扩展定义后如下:

    typedef struct {
      Py_ssize_t ob_refcnt;            // 引用计数
      struct _typeobject *ob_type;     // 类型指针
      Py_ssize_t ob_size// 字符串的长度,不计算C语言中的结尾NULL
      long ob_shash;                   // 字符串的hash值,没有计算则为-1
      int ob_sstate;                   // 字符串对象的状态: 是否interned等
      char ob_sval[1];                 // 保存字符串的内存,默认先分配1个字符,用来保存额外的末尾NULL值
     
      /* Invariants:
       *     ob_sval contains space for 'ob_size+1' elements.
       *     ob_sval[ob_size] == 0.
       *     ob_shash is the hash of the string or -1 if not computed yet.
       *     ob_sstate != 0 iff the string object is in stringobject.c's
       *       'interned' dictionary; in this case the two references
       *       from 'interned' to this object are *not counted* in ob_refcnt.
       */
    } PyStringObject;

    3 列表对象PyListObject;

    typedef struct {
        PyObject_VAR_HEAD
        #ob_item是用来保存元素的指针数组
        PyObject **ob_item;
        #allocated是ob_item预先分配的内存总容量
        Py_ssize_t allocated;
    } PyListObject;

    4 字典对象PyDictObject

    在Python中,字典是通过哈希表实现的。也就是说,字典是一个数组,而数组的索引是键经过哈希函数处理后得到的。哈希函数的目的是使键均匀地分布在数组中。由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化。

    以下基于C语言的数据结构用于存储字典的键/值对(也称作 entry),存储内容有哈希值,键和值。PyObject 是 Python 对象的一个基类。

    typedef struct {
        Py_ssize_t me_hash;
        PyObject *me_key;
        PyObject *me_value
    } PyDictEntry;

    下面为字典对应的数据结构。其中,ma_fill为活动槽以及哑槽(dummy slot)的总数。当一个活动槽中的键/值对被删除后,该槽则被标记为哑槽。ma_used为活动槽的总数。ma_mask值为数组的长度减 1 ,用于计算槽的索引。ma_table为数组本身,ma_smalltable为长度为 8 的初始数组。

    typedef struct _dictobject PyDictObject;
    struct _dictobject {
        PyObject_HEAD
        Py_ssize_t ma_fill;
        Py_ssize_t ma_used;
        Py_ssize_t ma_mask;
        PyDictEntry *ma_table;
        PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
        PyDictEntry ma_smalltable[PyDict_MINSIZE];
    };

    5 集合对象PySetObject

    setList对象相似,均为可变异构容器。但是其实现却和Dict类似,均为哈希表。具体的数据结构代码如下。

    typedef struct {
        long hash;      /* cached hash code for the entry key */
        PyObject *key;
    } setentry;
    
    /*
    This data structure is shared by set and frozenset objects.
    */
    typedef struct _setobject PySetObject;
    struct _setobject {
        PyObject_HEAD
        Py_ssize_t fill;  /* # Active + # Dummy */
        Py_ssize_t used;  /* # Active */
        /* The table contains mask + 1 slots, and that's a power of 2.
         * We store the mask instead of the size because the mask is more
         * frequently needed.
         */
        Py_ssize_t mask;
        /* table points to smalltable for small tables, else to
         * additional malloc'ed memory.  table is never NULL!  This rule
         * saves repeated runtime null-tests.
         */
        setentry *table;
        setentry *(*lookup)(PySetObject *so, PyObject *key, long hash);
        setentry smalltable[PySet_MINSIZE];
        long hash;                  /* only used by frozenset objects */
        PyObject *weakreflist;      /* List of weak references */
    };

    setentry是哈希表中的元素,记录插入元素的哈希值以及对应的Python对象。

    PySetObject是哈希表的具体结构:

    • fill 被填充的键的个数,包括Active和dummy,稍后解释具体意思
    • used 被填充的键中有效的个数,即集合中的元素个数
    • mask 哈希表的长度的掩码,数值为容量值减一
    • table 存放元素的数组的指针
    • smalltable 默认的存放元素的数组

    当元素较少时,所有元素只存放在smalltable数组中,此时table指向smalltable。当元素增多,会从新分配内存存放所有的元素,此时smalltable没有用,table指向新分配的内存。

    参考:

    TimeComplexity

    Python源码剖析—整数对象PyIntObject

    Python源码剖析—字符串对象PyStringObject

    Python中的List对象

    深入 Python 字典的内部实现

    Python的Set容器

    python中几个常见的“黑盒子”之 列表list

    python中几个常见的黑盒子之“字典dict” 与 “集合set”

  • 相关阅读:
    php configure help
    ubuntu下编译安装PHP
    【转】Ubuntu编译安装mysql源码
    Java 处理异常 9 个最佳实践,你知道几个?
    HashMap工作原理
    LinkedList
    SpringMVC常用注解@Controller,@Service,@repository,@Component
    HTML5 APP应用实现图片上传及拍照上传功能
    bootstrap-datepicker 与bootstrapValidator同时使用时,选择日期后,无法正常触发校验
    js
  • 原文地址:https://www.cnblogs.com/harvyxu/p/8538642.html
Copyright © 2011-2022 走看看