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。