Большая часть вашего замешательства связана с недопониманием прокси-объектов Flask, таких как session
, g
и request
.
Все, что делают эти объекты, - это убедитесь, что вы получаете правильные данные для текущего потока; они прокси между глобальным объектом (доступным для всех потоков, легко импортируемым и используемым в вашем коде Flask), объектом, хранящимся в локальном хранилище потоков , которое представляет собой объект, который прозрачно дифференцирует доступ к атрибутам по потокам Я бы. В этом нет необходимости блокировать или «ждать», прокси-объекты никогда не используются более чем одним потоком. session.foo
косвенно обращается и возвращает тот же объект, что и session._get_current_object().foo
(именно поэтому их идентификаторы всегда совпадают).
Таким образом, при доступе к объекту session
прокси становится прозрачным . Это не то, о чем вам когда-либо нужно беспокоиться, если вы не хотите поделиться прокси-объектом с другим потоком.
Прокси-объект, к которому вы обращаетесь, создается новым для каждого запроса . Это потому, что содержание сеанса зависит от данных в каждом запросе. Механизм сеансов Flask является подключаемым, но реализация по умолчанию хранит все данные в криптографически подписанном файле cookie, который необходимо декодировать в данные Python, если вы хотите иметь возможность взаимодействовать с ним. Каждый из ваших URL /create/
, /modify/
и /display/
обрабатывается как отдельные запросы, поэтому все они загружают данные сеанса из вашего запроса в новые объекты Python; их идентификаторы обычно отличаются.
После выполнения запроса объект сеанса снова исчезает. Вы не можете использовать это по-другому, потому что новый запрос, поступающий в тот же поток, должен представить данные сеанса из этого нового запроса в код Flask, а не данные из старого запроса.
Все это означает, что вывод id()
здесь не имеет смысла здесь. id()
- это число, уникальное для всех текущих активных объектов в текущем процессе Python. Это означает, что идентификаторы объектов, которые удалены из памяти, могут быть использованы повторно, просто потому, что вы видели одно и то же значение id()
в два момента времени, не означает, что у вас один и тот же объект. И то, что у вас одни и те же данные (равенство значений), не означает, что у вас в памяти один и тот же объект, даже если их идентификатор одинаков. Старый объект мог быть удален, а новый объект мог быть просто воссоздан с тем же значением.
Под капотом Flask вызывает метод open_session()
для объекта, назначенного Flask().session_interface
в начале каждого запроса. В конце вызывается метод save_session()
для повторного сохранения сеанса, и объект сеанса отбрасывается. Реализация по умолчанию - это SecureSessionInterface
объект , который ищет определенный cookie-файл в запросе и, если он присутствует и имеет действительную подпись, декодирует данные как тегированный JSON (компактная сериализация JSON) и возвращает SecureCookieSession
экземпляр с этими данными. Это объект, к которому session
относится прокси, и возвращается session._get_current_object()
. При сохранении данные снова сериализуются в тегированный JSON, подписываются и добавляются в ответ как исходящий заголовок Set-Cookie
.
Сохранение происходит только тогда, когда объект сеанса был «изменен» (session.modified
установлен на True
). Обратите внимание, что реализация по умолчанию устанавливает modified
в True
только при непосредственном манипулировании отображением сеанса (установка, обновление или удаление ключей в самом отображении), а не при изменении изменяемых объектов, хранящихся в сеансе; session['foo'] = 'bar'
обнаруживается, но если вы сохранили список или словарь в сеансе, то мутирование с такими выражениями, как session['spam'][0] = 'ham'
не будет обнаружено Либо заново установите изменяемый объект (session[key] = session[key]
), либо установите флаг modified
на True
вручную.