(Python学习3)字符串对象

typedef struct {
    PyObject_VAR_HEAD
    long ob_shash;          // 记录该字符串对象的hash值,避免重复计算
    int ob_sstate;          // 对象状态,是否interned
    char ob_sval[1];        // 实际存储的是字符串值的指针
} PyStringObject;

字符串对象模型如下,与《python源码剖析》中稍许不同


1、PyStringObject对象的创建

创建 PyStirngObjecet 时,先在对象池中查找,有则返回,无则创建并加入缓冲池。对象缓冲池为即为interned,实质为字典对象dict_object。

PyString_FromString(const char *str)      // 有删减
{
    register size_t size;
    register PyStringObject *op;
    size = strlen(str);

   if (size == 0 && (op = nullstring) != NULL) {
        return (PyObject *)op;
   if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) {
        return (PyObject *)op;

   op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);   // 创建对象
   ……    
  
    /* 将长度较短PyStringObject对象加入对象池 */	
    if (size == 0)
        ……
    else if (size == 1)
        ……
    return (PyObject *) op;
}

size为0返回nullstring,size为1在字符缓冲池中查找并返回。

其实更长的字符串也共享了对象池,却没有找到代码。

2、Intern机制

PyString_InternInPlace(PyObject **p){                   // 有删减
    PyStringObject *s = (PyStringObject *)(*p);
	……
    if (interned == NULL)
        interned = PyDict_New();
    t = PyDict_GetItem(interned, (PyObject *)s);
    if (PyDict_SetItem(interned, (PyObject *)s, (PyObject *)s) < 0)
        ……
}
由上函数可以看出,对象池interned实质为字典对象,并且key与value都是同一个PyStringObject对象的指针。并且在查找前需要创建临时PyStringObject对象作为key。


3、字符缓冲池

static PyStringObject *characters[UCHAR_MAX + 1];
characters[]中存储了256个单字符的PyStringObject对象的指针。

characters[*str & UCHAR_MAX]   // 此语句即可直接定位到 str 对象的指针


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值