2. Python3源码—浮点对象

2.1. 浮点对象

浮点对象是“定长对象”。

2.1.1. Python中的创建

Python中浮点对象创建最重要的方法为PyFloat_FromDouble,如下Python语句最终会调用到PyFloat_FromDouble:

a = 1.23
b = float(1.234)

2.1.2. PyFloat_FromDouble的C调用栈

词法解析,最终调到PyFloat_FromDouble,调用顺序如下:

// ast.c
ast_for_expr
=>ast_for_power
=>ast_for_atom_expr
=>ast_for_atom (case NUMBER)
=>parsenumber
=>parsenumber_raw

// floatobject.c
=> PyFloat_FromDouble

2.1.3. PyFloat_FromDouble的C源码

// floatobject.c
PyObject *
PyFloat_FromDouble(double fval)
{
    PyFloatObject *op = free_list;
    if (op != NULL) {
        free_list = (PyFloatObject *) Py_TYPE(op);
        numfree--;
    } else {
        op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject));
        if (!op)
            return PyErr_NoMemory();
    }
    /* Inline PyObject_New */
    (void)PyObject_INIT(op, &PyFloat_Type);
    op->ob_fval = fval;
    return (PyObject *) op;
}

可以看到:

  • 浮点对象的C数据结构,所以Python中的浮点对象,实际上是C中的double。
// floatobject.h
typedef struct {
    PyObject_HEAD
    double ob_fval;
} PyFloatObject;
  • 采用浮点对象缓冲池
// floatobject.c
#ifndef PyFloat_MAXFREELIST
#define PyFloat_MAXFREELIST    100
#endif
static int numfree = 0;
static PyFloatObject *free_list = NULL;

static void
float_dealloc(PyFloatObject *op)
{
    if (PyFloat_CheckExact(op)) {
        if (numfree >= PyFloat_MAXFREELIST)  {
            PyObject_FREE(op);
            return;
        }
        numfree++;
        Py_TYPE(op) = (struct _typeobject *)free_list;
        free_list = op;
    }
    else
        Py_TYPE(op)->tp_free((PyObject *)op);
}

PyObject *
PyFloat_FromDouble(double fval)
{
    PyFloatObject *op = free_list;
    if (op != NULL) {
        free_list = (PyFloatObject *) Py_TYPE(op);
        numfree--;
    } else {
        op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject));
        if (!op)
            return PyErr_NoMemory();
    }
    /* Inline PyObject_New */
    (void)PyObject_INIT(op, &PyFloat_Type);
    op->ob_fval = fval;
    return (PyObject *) op;
}

float_dealloc和PyFloat_FromDouble方法针对free_list和numfree的操作构成了Python的浮点对象缓冲池技术。采用链表,值得注意的是Py_TYPE(op),在此处被当做next指针。缓冲池大小有上限,Python3中为100。

  • PyObject_INIT
    因为是定长对象,所以调用PyObject_INIT方法,与PyObject_INIT_VAR方法相比,只是少调用Py_SIZE(op) = (size)

2.2. 浮点对象的特性

2.2.1. 数值计算

// floatobject.c
&float_as_number,                           /* tp_as_number */

浮点对象的数值计算由float_as_number定义:

// floatobject.c
static PyNumberMethods float_as_number = {
    float_add,          /* nb_add */
    float_sub,          /* nb_subtract */
    float_mul,          /* nb_multiply */
    float_rem,          /* nb_remainder */
    float_divmod,       /* nb_divmod */
    float_pow,          /* nb_power */
    (unaryfunc)float_neg, /* nb_negative */
    float_float,        /* nb_positive */
    (unaryfunc)float_abs, /* nb_absolute */
    (inquiry)float_bool, /* nb_bool */
    0,                  /* nb_invert */
    0,                  /* nb_lshift */
    0,                  /* nb_rshift */
    0,                  /* nb_and */
    0,                  /* nb_xor */
    0,                  /* nb_or */
    float___trunc___impl, /* nb_int */
    0,                  /* nb_reserved */
    float_float,        /* nb_float */
    0,                  /* nb_inplace_add */
    0,                  /* nb_inplace_subtract */
    0,                  /* nb_inplace_multiply */
    0,                  /* nb_inplace_remainder */
    0,                  /* nb_inplace_power */
    0,                  /* nb_inplace_lshift */
    0,                  /* nb_inplace_rshift */
    0,                  /* nb_inplace_and */
    0,                  /* nb_inplace_xor */
    0,                  /* nb_inplace_or */
    float_floor_div,    /* nb_floor_divide */
    float_div,          /* nb_true_divide */
    0,                  /* nb_inplace_floor_divide */
    0,                  /* nb_inplace_true_divide */
};

2.2.2. to string

// floatobject.c
(reprfunc)float_repr,                       /* tp_repr */
(reprfunc)float_repr,                       /* tp_str */

2.2.3. hash

// floatobject.c
(hashfunc)float_hash,                       /* tp_hash */

2.2.4. 比较

// floatobject.c
float_richcompare,                        /* tp_richcompare */

2.2.5. 内置方法

// floatobject.c
float_methods,                              /* tp_methods */

2.2.6. 内置属性

// floatobject.c
float_getset,                                /* tp_getset */

2.3 参考

  • Python源码剖析
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 1、基于Python+Django的框架图书管理系统(源码+数据库+项目说明).zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 # python_django_book # Python基于Django框架图书管理系统 程序开发软件:Pycharm 数据库:mysql 采用技术: Django(一个MVT框架,类似Java的SSM框架) 人生苦短,我用Python,咱们今天就来分享一个用Python语言开发的基于Django框架的图书管理系统吧。项目前台和后台界面模板都是自己编写,前台采用Bootstrap框架UI,后台EasyUI框架UI,没有采用Django自动生成的那个后台管理,因为那个后台实在是太丑了,丑得惨不忍睹!整个项目主要负责图书信息的添加,修改,多个条件组合查询,删除。虽然系统功能不是很复杂,不过这是一个很好的学习案例,包括了常用字段的设计,比如字符串,浮点型,整型,日期型,图片型,富文本字符串型,文件型和下拉框外键关联型,囊括了所有商业项目设计需要的字段类型,通杀所有商业系统设计原理!当然也是学习的不二选择,好东西值得分享,强烈推荐! 系统实体对象: 图书类型:图书类别,类别名称,可借阅天数 图书:图书条形码,图书名称,图书所在类别,图书价格,库存,出版日期,出版社,图书图片,图书简介,图书文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值