zoukankan      html  css  js  c++  java
  • python3 整数类型PyLongObject 和PyObject源码分析

    python3 整数类型PyLongObject 和PyObject源码分析
    一 测试环境介绍和准备
    测试环境:
    操作系统:windows10
    Python版本:3.7.0 下载地址
    VS版本:vs2015社区版(免费) 下载地址
    win10SDK(安装vs2015是可以选择,如果没有安装则需要独立安装)
    二 如何查看源码
    1 下载python源码
    下载后解压缩
    使用vs2015或者vs2017打开
    Python-3.7.0PCbuildpcbuild.sln 解决方案文件
    打开pythoncore项目可以找到includeobject.h文件
     
    三 源码分析
    python源码版本 python3.7.0
    在python中所有的类型都可以转为PyObject类型,单python用的是c语言,并没有继承机制,我们可以通过源码看它试如何实现的,我们先看PyObject源码
    1 PyObject 源码
    typedef struct _object {
    _PyObject_HEAD_EXTRA
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
    } PyObject;
     
    1-1 _PyObject_HEAD_EXTRA 源码
    我们先看第一个成员是一个宏 _PyObject_HEAD_EXTRA,这个宏是如下定义
    #ifdef Py_TRACE_REFS
    /* Define pointers to support a doubly-linked list of all live heap objects. */
    #define _PyObject_HEAD_EXTRA
    struct _object *_ob_next;
    struct _object *_ob_prev;
     
    #define _PyObject_EXTRA_INIT 0, 0,
     
    #else
    #define _PyObject_HEAD_EXTRA
    #define _PyObject_EXTRA_INIT
    #endif
     
    通过代码我们可以看出,它根据环境给_PyObject_HEAD_EXTRA设置的值有可能是空的,或者是一个双向链表。通过编译代码我们知道,他在debug版本的python中是用的双向链表,而在release版本中是空。
    1-2 Py_ssize_t ob_refcnt 引用计数
    Py_ssize_t 类型在32位程序中就是int,在64位win程序中是__int64
    引用计数的策略后面我们专门写文章分析
    1-3 struct _typeobject *ob_type;
    源码比较长,就不全部列出来,这个结构体中包含了一个PyObject对象的所有相关操作函数和属性,比如对象创建和销毁函数,print对象的序列化函数等,存储方式都是通过函数指针。所以每种python类型都会对各类操作函数指针做赋值设定。
    其中的PyObject_VAR_HEAD宏内容如下
    typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
    } PyVarObject;
     
     
    2 PyLongObject 整数对象
     
    digit
    struct _longobject {
    PyObject_VAR_HEAD
    digit ob_digit[1];
    };
     
     
    2-1 小数预处理
    对于比较小的数(-5到257 )直接返回初始化好的值,所以说大量的小整数时,不会新增额外的空间
    do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
    return get_small_int((sdigit)ival);
    } while(0)
     
    2-2 按照数字的发小分配空间,以unsigned short为单位
    数字少于16位也就是2个字节的,用一个digit (unsigned short) 存放
    数字少于32位也就是4个字节的,用两个个digit (unsigned short) 存放
    2-3 大数处理
    如果是超大数,就用多个字节存放,由于变量就是一个 unsigned long,先看一下源码:
    对于不同的系统,大数能表示的范围不一致,因为数字采用的是unsigned long存放,在不同的系统大小不一致,可以见如下表
     
    其中 windows 64位使用的是 LLP64所以 在window中python数字的最大值也就是4个字节,如果用它来存放64位指针的地址,就会丢失数据。
    在linux(ubuntu16.04 64)使用的是LP64,,所以数字最大值就是8个字节。
     
    相关视频可以观看

     

    http://laoxiaketang.com/python.html

  • 相关阅读:
    NPOIHelper
    NPOI.dll 用法:单元格、样式、字体、颜色、行高、宽度 读写excel
    SQL中的循环、for循环、游标
    .net mvc datatables中orderby动态排序
    MVC中给TextBoxFor设置默认值和属性
    定义实体系列-@JsonIgnoreProperties注解
    微信公众号登录与微信开放平台登录区别
    http-Post请求,Post Body中的数据量过大时出现的问题
    .net core Linux 安装部署
    二、微信公众号开发-获取微信用户信息(.net版)
  • 原文地址:https://www.cnblogs.com/xiacaojun/p/9988924.html
Copyright © 2011-2022 走看看