Python中字符串对象的实现原理是什么

  

Python中字符串对象的实现原理是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

在Python世界中将对象分为两种:一种是定长对象,比如整数,整数对象定义的时候就能确定它所占用的内存空间大小,另一种是变长对象,在对象定义时并不知道是多少,比如:str,列表,设置,dict等。

在祝辞祝辞import 系统   在祝辞祝辞,sys.getsizeof (1000)   28   在祝辞祝辞,sys.getsizeof (2000)   28   在祝辞祝辞,sys.getsizeof (“python")   55   在祝辞祝辞,sys.getsizeof (“java")   53

如上,整数对象所占用的内存都是28字节,和具体的值没关系,而同样都是字符串对象,不同字符串对象所占用的内存是不一样的,这就是变长对象,对于变长对象,在对象定义时是不知道对象所占用的内存空间是多少的。

字符串对象在Python内部用PyStringObject表示,PyStringObject和PyIntObject一样都属于不可变对象,对象一旦创建就不能改变其值。(注意:变长对象和不可变对象是两个不同的概念).PythonStringObject的定义:

[stringobject.h]   typedef  struct  {   PyObject_VAR_HEAD   long  ob_shash;   int  ob_sstate;   char  ob_sval [1];   },PyStringObject;

不难看出Python的字符串对象内部就是由一个字符数组维护的,在整数的实现原理一文中提到PyObject_HEAD,对于PyObject_VAR_HEAD就是在PyObject_HEAD基础上多出一个ob_size属性:

[object.h]   # define  PyObject_VAR_HEAD ,   PyObject_HEAD ,大敌;   ,int  ob_size;/*, Number  of  items 拷贝variable  part  */typedef  struct  {   ,PyObject_VAR_HEAD   },PyVarObject; <李>

ob_size保存了变长对象中元素的长度,比如PyStringObject对象“Python"的ob_size为6 .

<李>

ob_sval是一个初始大小为1的字符数组,且ob_sval[0]=& # 39; \ 0 & # 39;,但实际上创建一个PyStringObject时ob_sval指向的是一段长为ob_size + 1个字节的内存。

<李>

ob_shash是字符串对象的哈希值,初始值为1,在第一次计算出字符串的哈希值后,会把该值缓存下来,赋值给ob_shash。

<李>

ob_sstate用于标记该字符串对象是否进过实习生机制处理(后文会介绍)。

<强> PyStringObject对象创建过程

[stringobject.c]   PyObject  *, PyString_FromString (const  char  * str)   {   register  size_t 规模;   register  PyStringObject  * op;   断言(str  !=, NULL);   时间=size  strlen (str);//,[1]   if  (size 祝辞,PY_SSIZE_T_MAX 作用;PyStringObject_SIZE), {   PyErr_SetString (PyExc_OverflowError   “string  is  too  long  for  a  Python  string");   return 零;   }//,[2]   if  (size ==, 0,,,, (=op  nullstring), !=, NULL), {   # ifdef  COUNT_ALLOCS   null_strings + +;   # endif   Py_INCREF (op);   return  (PyObject  *)人事处;   }//,[3]   if  (size ==, 1,,,, (=op 字符[* str ,, UCHAR_MAX]), !=, NULL), {   # ifdef  COUNT_ALLOCS   one_strings + +;   # endif   Py_INCREF (op);   return  (PyObject  *)人事处;   }//,[4]/*,Inline  PyObject_NewVar  */op =, (PyStringObject  *) PyObject_MALLOC(时间+ PyStringObject_SIZE 大小);   if  (op ==, NULL)   return  PyErr_NoMemory ();   PyObject_INIT_VAR (op,,, PyString_Type,,大小);   op→ob_shash =, 1;   op→ob_sstate =, SSTATE_NOT_INTERNED;   Py_MEMCPY (op→ob_sval, str,,大小+ 1);/*,share  short  strings  */if  (size ==, 0), {   PyObject  * t =, op (PyObject  *);   PyString_InternInPlace(及t);   op =, (PyStringObject  *) t;   nullstring =,人事处;   Py_INCREF (op);   },else  if  (size ==, 1), {   PyObject  * t =, op (PyObject  *);   PyString_InternInPlace(及t);   op =, (PyStringObject  *) t;   字符[* str ,, UCHAR_MAX],=,人事处;   Py_INCREF (op);   }   return  (PyObject  *),人事处;   } <李>

如果字符串的长度超出了Python所能接受的最大长度(32位平台是2 g),则返回零。

<李>

如果是空字符串,那么返回特殊的PyStringObject,即nullstring。

Python中字符串对象的实现原理是什么