创建一个PyStringObject对象,通常Python会申请内存,创建一个PyStringObject对象。而若是申请很多个相同的对象,则会大量浪费内存。因此,Python引入了intern机制,在创建一个String对象的时候,先查找是否已经创建过内容相同的对象,如果有,则直接将已有的对象地址返回,否则就新创建。
void PyString_InternInPlace(PyObject **p) { register PyStringObject *s = (PyStringObject *)(*p); PyObject *t; if (s == NULL || !PyString_Check(s)) Py_FatalError("PyString_InternInPlace: strings only please!"); /* If it's a string subclass, we don't really know what putting it in the interned dict might do. */ if (!PyString_CheckExact(s)) return; if (PyString_CHECK_INTERNED(s)) return; if (interned == NULL) { interned = PyDict_New(); if (interned == NULL) { PyErr_Clear(); /* Don't leave an exception */ return; } } t = PyDict_GetItem(interned, (PyObject *)s); if (t) { Py_INCREF(t); Py_DECREF(*p); *p = t; return; } if (PyDict_SetItem(interned, (PyObject *)s, (PyObject *)s) < 0) { PyErr_Clear(); return; } /* The two references in interned are not counted by refcnt. The string deallocator will take care of this */ Py_REFCNT(s) -= 2; PyString_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL; }
实际上,Python还是会创建这一个String对象,然而在创建后,若是存在相同的,则会将String的ob_refcn置为0,对象被析构。