{人面不知何去处 桃花依旧笑春风}

py3源码[3]-其它数值类型

Posted in Uncategorized by interma on 2012/10/23

除了PyIntObject(2.x)和PyLongObject之外,还有如下几种数值类型:

一,bool

//boolobject.c
//True和False都是对PyLongObject的一个封装
struct _longobject _Py_FalseStruct = {
    PyVarObject_HEAD_INIT(&PyBool_Type, 0) //ob_size=0
    { 0 } //ob_digit=0
};
struct _longobject _Py_TrueStruct = {
    PyVarObject_HEAD_INIT(&PyBool_Type, 1) //ob_size=1
    { 1 }
};

tips:
1,bool的tp_base是PyLong_Type,所以可以:
>>> a=[1,2,3]
>>> a[True]
2
>>> 1==True
True
>>> 0==False
True
2,判断object是否为True,”所有零值或内容长度为零的对象都被视为False”。

//object.c
int
PyObject_IsTrue(PyObject *v)
{
    Py_ssize_t res;
    if (v == Py_True)
        return 1;
    if (v == Py_False)
        return 0;
    if (v == Py_None)
        return 0;
    else if (v->ob_type->tp_as_number != NULL &&
             v->ob_type->tp_as_number->nb_bool != NULL)
        res = (*v->ob_type->tp_as_number->nb_bool)(v);
    else if (v->ob_type->tp_as_mapping != NULL &&
             v->ob_type->tp_as_mapping->mp_length != NULL)
        res = (*v->ob_type->tp_as_mapping->mp_length)(v);
    else if (v->ob_type->tp_as_sequence != NULL &&
             v->ob_type->tp_as_sequence->sq_length != NULL)
        res = (*v->ob_type->tp_as_sequence->sq_length)(v);
    else
        return 1;
    /* if it is negative, it should be either -1 or -2 */
    return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int);
}

二,float

//floatobject.h
typedef struct {
    PyObject_HEAD //定长对象
    double ob_fval; //内部使用c double类型包装
} PyFloatObject;

tips:
1,也使用了free_list,不过区别于2.x中的PyIntObject,free_list有最长长度限制

#ifndef PyFloat_MAXFREELIST
#define PyFloat_MAXFREELIST    100 
#endif
static int numfree = 0;
static PyFloatObject *free_list = NULL;

PyObject * PyFloat_FromDouble(double fval)
{
    register PyFloatObject *op = free_list;
    if (op != NULL) { //free_list中有空间,直接用
        free_list = (PyFloatObject *) Py_TYPE(op);
        numfree--;
    } else { //否则,malloc出来即可
        op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject));
        if (!op)
            return PyErr_NoMemory();
    }
    /* Inline PyObject_New */
    PyObject_INIT(op, &PyFloat_Type);
    op->ob_fval = fval;
    return (PyObject *) op;
}

static void float_dealloc(PyFloatObject *op)
{
    if (PyFloat_CheckExact(op)) {
        if (numfree >= PyFloat_MAXFREELIST)  { // 超出最大长度就直接free掉
            PyObject_FREE(op);
            return;
        }
        numfree++;
        Py_TYPE(op) = (struct _typeobject *)free_list;
        free_list = op;
    }
    else
        Py_TYPE(op)->tp_free((PyObject *)op);
}

三,复数

//complexobjec.h
typedef struct {
    double real;
    double imag;
} Py_complex;

>>> a=complex(1.2,1.5)
>>> a
(1.2+1.5j)

四,分数
lib实现:import fractions。
不赘述,请参考:http://woodpecker.org.cn/diveintopython3/native-datatypes.html

参考:
1,雨痕-深入Python编程-RC0.3.pdf
2,http://woodpecker.org.cn/diveintopython3/

Tagged with:

留下评论