Одна важная особенность этого поведения состоит в том, что Python кэширует некоторые, в основном, короткие строки (обычно не более 20 символов, но не для каждой их комбинации), чтобы они стали быстро доступными.Одной из важных причин этого является то, что строки широко используются в исходном коде Pyhton, и это внутренняя оптимизация для кэширования некоторых специальных типов строк.Словари являются одной из обычно используемых структур данных в исходном коде Python, которые используются для сохранения переменных, атрибутов и пространств имен в целом, а также для некоторых других целей, и все они используют строки в качестве имен объектов.Это значит, что каждый раз, когда вы пытаетесь получить доступ к атрибуту объекта или иметь доступ к переменной (локальной или глобальной), появляется словарь, который запускается изнутри.
Теперь причина, по которой вы получили такое странное поведение, заключается в том, что Python (реализация Cpython) по-разному обрабатывает строки в терминах интернирования.В исходном коде Python есть функция intern_string_constants , которая дает строкам проверяемую информацию для проверки, которую вы можете проверить для получения более подробной информации.Или посмотрите эту всеобъемлющую статью http://guilload.com/python-string-interning/.
Также стоит отметить, что Python имеет функцию intern()
в модуле sys
, которую можно использовать для интернирования строк вручную.
In [52]: b = sys.intern('a,,')
In [53]: c = sys.intern('a,,')
In [54]: b is c
Out[54]: True
YouВы можете использовать эту функцию, когда хотите закрепить поиск по словарю или когда вам нужно часто использовать конкретный строковый объект в вашем коде.
Другой моментчто не следует путать с интернирование строк в том, что когда вы делаете a == b
, вы создаете две ссылки на один и тот же объект, что очевидно для этих ключевых слов, чтобы иметь одинаковые id
.
Что касается знаков препинания, кажется, что если они являются одним символом, их интернируют, если их длина больше единицы. Если длина больше единицы, они не будут кэшироваться.Как уже упоминалось в комментариях, одна из причин этого может заключаться в том, что в ключевых словах и словарных ключах меньше знаков препинания.
In [28]: a = ','
In [29]: ',' is a
Out[29]: True
In [30]: a = 'abc,'
In [31]: 'abc,' is a
Out[31]: False
In [34]: a = ',,'
In [35]: ',,' is a
Out[35]: False
# Or
In [36]: a = '^'
In [37]: '^' is a
Out[37]: True
In [38]: a = '^%'
In [39]: '^%' is a
Out[39]: False
Но все же это всего лишь некоторые предположения, на которые нельзя полагаться в своих кодах,