Spec-Zone.ru › Werkzeug 2.0

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

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

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

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

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

Вот простой пример того, как можно использовать 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 (если вы используете greenlet), один и тот же поток и один и тот же процесс.

Если объект запроса ещё не установлен в локальном объекте, и вы попытаетесь к нему обратиться, вы получите 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, ident_func=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]]]) –
  • ident_func (None) –
Тип возвращаемого значения

None

cleanup()

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

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

None

get_ident()

Возвращает идентификатор контекста, который локальные объекты используют внутри этого контекста. Вы не можете переопределить этот метод, чтобы изменить поведение, но можете использовать его для связывания других локальных объектов контекста (например, отсортированных сессий SQLAlchemy) с локальными переменными Werkzeug.

Устарело начиная с версии 2.0: Будет удалено в Werkzeug 2.1.

Изменения

Изменено в версии 0.7: Вы можете передать функцию для определения идентификатора в менеджер локальных переменных, которая затем будет распространена на все локальные переменные, переданные в конструктор.

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

int

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()

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

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

Любой

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

Spec-Zone.ru

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