Spec-Zone.ru › Werkzeug 2.1

Локальные переменные контекста

В какой-то момент вам потребуются данные, доступные во всех представлениях или вспомогательных функциях. В PHP для этого используются глобальные переменные. Однако в приложениях WSGI это невозможно без существенного недостатка: как только вы работаете с глобальным пространством имён, ваше приложение больше не является потокобезопасным.

Стандартная библиотека Python содержит понятие «поточные локальные переменные» (или данные, локальные для потока). Потоковая локальная переменная — это глобальный объект, в который можно поместить данные и получить их обратно позже безопасным и специфичным для потока способом. Это означает, что каждый раз при установке или получении значения в объекте потоковой локальной переменной, объект проверяет, в каком потоке вы находитесь, и извлекает значение, соответствующее вашему потоку (если оно существует). Таким образом, вы случайно не получите данные другого потока.

Однако этот подход имеет несколько недостатков. Например, помимо потоков, в Python существуют и другие типы конкурентности. Очень популярны, например, greenlets. Также не гарантируется, что каждый запрос получит свой собственный поток в WSGI. Возможно, запрос использует поток из предыдущего запроса, и в результате данные остаются в объекте потоковой локальной переменной.

Werkzeug предоставляет собственную реализацию хранения локальных данных, называемую werkzeug.local. Этот подход обеспечивает функциональность, похожую на потоковые локальные переменные, но также работает с greenlets.

Вот простой пример использования werkzeug.local:

from werkzeug.local import Local, LocalManager

local = Local()
local_manager = LocalManager([local])

def application(environ, start_response):
    local.request = request = Request(environ)
    ...

application = local_manager.make_middleware(application)

Это привязывает запрос к local.request. Любой другой фрагмент кода, выполняемый после этого присваивания в том же контексте, может безопасно получить доступ к local.request и получит тот же объект запроса. Метод make_middleware в менеджере локальных переменных гарантирует, что все ссылки на локальные объекты будут удалены после обработки запроса.

Один и тот же контекст означает один и тот же greenlet (если вы используете greenlets), в том же потоке и том же процессе.

Если объект запроса ещё не установлен в локальный объект, и вы пытаетесь получить к нему доступ, вы получите AttributeError. Вы можете использовать getattr для избежания этого:

def get_request():
    return getattr(local, 'request', None)

Это попытается получить запрос или вернуть None если запрос ещё недоступен.

Обратите внимание, что локальные объекты не могут управлять собой, для этого нужен менеджер локальных переменных. Вы можете передать менеджеру локальные переменные или добавить дополнительные позже, добавив их в manager.locals. Каждый раз, когда менеджер выполняет очистку, он очистит все данные, оставшиеся в локальных переменных для данного контекста.

werkzeug.local.release_local(local)

Освобождает содержимое локальной переменной для текущего контекста. Это позволяет использовать локальные переменные без менеджера.

Пример:

>>> loc = Local()
>>> loc.foo = 42
>>> release_local(loc)
>>> hasattr(loc, 'foo')
False

С помощью этой функции можно освободить Local объекты, а также LocalStack объекты. Однако невозможно освободить данные, хранящиеся в прокси-объектах таким образом, вы всегда должны сохранить ссылку на базовый локальный объект, чтобы иметь возможность его освободить.

Изменения

Добавлена в версии 0.6.1.

Параметры

local (Union[werkzeug.local.Local, werkzeug.local.LocalStack]) –

Тип возвращаемого значения

None

class werkzeug.local.LocalManager(locals=None)

Локальные объекты не могут управлять собой. Для этого нужен менеджер локальных переменных. Вы можете передать менеджеру локальные переменные или добавить их позже, добавив их в manager.locals. Каждый раз, когда менеджер выполняет очистку, он очистит все данные, оставшиеся в локальных переменных для данного контекста.

Изменения

Изменено в версии 2.0: ident_func устарело и будет удалено в Werkzeug 2.1.

Изменено в версии 0.7: Добавлен параметр ident_func.

Изменено в версии 0.6.1: Вместо менеджера можно использовать функцию release_local().

Параметры

locals (Optional[Iterable[Union[werkzeug.local.Local, werkzeug.local.LocalStack]]]) –

Тип возвращаемого значения

None

cleanup()

Вручную очистите данные в локальных переменных для этого контекста. Вызовите эту функцию в конце обработки запроса или используйте make_middleware().

Тип возвращаемого значения

None

make_middleware(app)

Оборачивает WSGI-приложение, чтобы очистка происходила после завершения запроса.

Параметры

app (WSGIApplication) –

Тип возвращаемого значения

WSGIApplication

middleware(func)

Аналогично make_middleware, но для декорирования функций.

Пример использования:

@manager.middleware
def application(environ, start_response):
    ...

Отличие от make_middleware состоит в том, что функции, переданной, будут скопированы все аргументы из внутреннего приложения (имя, строка документации, модуль).

Параметры

func (WSGIApplication) –

Тип возвращаемого значения

WSGIApplication

class werkzeug.local.LocalStack

Этот класс работает аналогично Local, но хранит стек объектов вместо одного. Это лучше всего объяснить на примере:

>>> ls = LocalStack()
>>> ls.push(42)
>>> ls.top
42
>>> ls.push(23)
>>> ls.top
23
>>> ls.pop()
23
>>> ls.top
42

Их можно принудительно освободить, используя LocalManager или с помощью функции release_local(), но правильный способ — извлечь элемент из стека после его использования. Когда стек пуст, он больше не будет связан с текущим контекстом (и таким образом, будет освобождён).

Вызывая стек без аргументов, вы получите прокси, который ссылается на самый верхний элемент в стеке.

Изменения

Добавлена в версии 0.6.1.

Тип возвращаемого значения

None

pop()

Удаляет самый верхний элемент из стека, возвращает старое значение или None если стек был уже пуст.

Тип возвращаемого значения

Any

push(obj)

Добавляет новый элемент в стек

Параметры

obj (Any) –

Тип возвращаемого значения

List[Any]

property top: Any

Самый верхний элемент в стеке. Если стек пуст, возвращается None.

class werkzeug.local.LocalProxy(local, name=None)

Провайдер для объекта, связанного с Local. Все операции с провайдером передаются связанному объекту. Если объект не связан, возникает исключение RuntimeError.

from werkzeug.local import Local
l = Local()

# a proxy to whatever l.user is set to
user = l("user")

from werkzeug.local import LocalStack
_request_stack = LocalStack()

# a proxy to _request_stack.top
request = _request_stack()

# a proxy to the session attribute of the request proxy
session = LocalProxy(lambda: request.session)

__repr__ и __class__ передаются, поэтому repr(x) и isinstance(x, cls) будут выглядеть как проксируемый объект. Используйте issubclass(type(x), LocalProxy) для проверки, является ли объект прокси.

repr(user)  # <User admin>
isinstance(user, User)  # True
issubclass(type(user), LocalProxy)  # True
Параметры
  • local – Local или вызываемый объект, предоставляющий проксируемый объект.
  • name – Имя атрибута для поиска в Local. Не используется, если задан вызываемый объект.
Журнал изменений

Изменено в версии 2.0: Обновлены проксируемые атрибуты и методы для отражения текущей модели данных.

Изменено в версии 0.6.1: Класс может быть создан с вызываемым объектом.

_get_current_object()

Возвращает текущий объект. Это полезно, если вам нужен реальный объект за прокси в какой-то момент по причинам производительности или потому что вы хотите передать объект в другой контекст.

Тип возвращаемого значения

Any

© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://werkzeug.palletsprojects.com/en/2.1.x/local/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API