前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python3 整数类型PyLongOb

python3 整数类型PyLongOb

作者头像
py3study
发布2020-01-03 10:51:43
5750
发布2020-01-03 10:51:43
举报
文章被收录于专栏:python3python3

python3 整数类型PyLongObject 和PyObject源码分析 一 测试环境介绍和准备 测试环境: 操作系统:windows10 Python版本:3.7.0 下载地址 VS版本:vs2015社区版(免费) 下载地址 win10SDK(安装vs2015是可以选择,如果没有安装则需要独立安装) http://ffmpeg.club/python 二 如何查看源码 1 下载python源码 https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz http://www.ffmpeg.club/python 下载后解压缩 使用vs2015或者vs2017打开 Python-3.7.0\PCbuild\pcbuild.sln 解决方案文件

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

打开pythoncore项目可以找到\include\object.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;

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和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

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

通过代码我们可以看出,它根据环境给_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;

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

源码比较长,就不全部列出来,这个结构体中包含了一个PyObject对象的所有相关操作函数和属性,比如对象创建和销毁函数,print对象的序列化函数等,存储方式都是通过函数指针。所以每种python类型都会对各类操作函数指针做赋值设定。 其中的PyObject_VAR_HEAD宏内容如下 typedef struct { PyObject ob_base; Py_ssize_t ob_size; / Number of items in variable part */ } PyVarObject;

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

2 PyLongObject 整数对象

digit struct _longobject { PyObject_VAR_HEAD digit ob_digit[1]; };

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

2-1 小数预处理 对于比较小的数(-5到257 )直接返回初始化好的值,所以说大量的小整数时,不会新增额外的空间 do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \ return get_small_int((sdigit)ival); \ } while(0)

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

2-2 按照数字的发小分配空间,以unsigned short为单位 数字少于16位也就是2个字节的,用一个digit (unsigned short) 存放

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

数字少于32位也就是4个字节的,用两个个digit (unsigned short) 存放

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

2-3 大数处理 如果是超大数,就用多个字节存放,由于变量就是一个 unsigned long,先看一下源码:

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

对于不同的系统,大数能表示的范围不一致,因为数字采用的是unsigned long存放,在不同的系统大小不一致,可以见如下表

python3 整数类型PyLongObject 和PyObject源码分析
python3 整数类型PyLongObject 和PyObject源码分析

其中 windows 64位使用的是 LLP64所以 在window中python数字的最大值也就是4个字节,如果用它来存放64位指针的地址,就会丢失数据。 在linux(ubuntu16.04 64)使用的是LP64,,所以数字最大值就是8个字节。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档