Ответ 1
Они не одно и то же на всех.
len()
для количества элементов, содержащихся в контейнере. Для строки, в которой количество символов:
Возвращает длину (количество элементов) объекта. Аргументом может быть последовательность (строка, кортеж или список) или сопоставление (словарь).
sys.getsizeof()
с другой стороны возвращает размер памяти объекта:
Возвращает размер объекта в байтах. Объектом может быть любой тип объекта. Все встроенные объекты вернут правильные результаты, но это не должно быть верно для сторонних расширений, поскольку это специфичная реализация.
Строковые объекты Python - это не простые последовательности символов, 1 байт на символ.
В частности, sys.getsizeof()
включает служебные данные сборщика мусора, если таковые имеются:
getsizeof()
вызывает метод__sizeof__
и добавляет дополнительные служебные данные сборщика мусора, если объект управляется сборщиком мусора.
Объекты String не нужно отслеживать (они не могут создавать циклические ссылки), но строковым объектам требуется больше памяти, чем только байты на символ. В Python 2 возвращается метод __sizeof__
(в коде C):
Py_ssize_t res;
res = PyStringObject_SIZE + PyString_GET_SIZE(v) * Py_TYPE(v)->tp_itemsize;
return PyInt_FromSsize_t(res);
где PyStringObject_SIZE
- это размер заголовка структуры C для типа, PyString_GET_SIZE
основном такой же, как len()
а Py_TYPE(v)->tp_itemsize
- размер каждого символа. В Python 2.7 для строк байтов размер каждого символа равен 1, но это PyStringObject_SIZE
который вас путает; на моем Mac этот размер равен 37 байтам:
>>> sys.getsizeof('')
37
Для строк unicode
размер каждого символа увеличивается до 2 или 4 (в зависимости от параметров компиляции). В Python 3.3 и новее строки Unicode занимают от 1 до 4 байтов на символ, в зависимости от содержимого строки.