Как будто вы пытаетесь получить доступ к объекту, который является null
. Рассмотрим ниже пример:
TypeA objA;
. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException
, что имеет смысл.
См. Также этот пример:
String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
Давайте возьмем один пример, предположим, что вы хотите установить usercontext (используя конструкцию флагов Local и LocalProxy).
Определить один класс пользователя:
class User(object):
def __init__(self):
self.userid = None
определить функцию для извлечения пользовательского объекта внутри текущего потока или greenlet
def get_user(_local):
try:
# get user object in current thread or greenlet
return _local.user
except AttributeError:
# if user object is not set in current thread ,set empty user object
_local.user = User()
return _local.user
Теперь определите LocalProxy
usercontext = LocalProxy(partial(get_user, Local()))
Теперь, чтобы получить идентификатор пользователя в текущем потоке usercontext.userid
:
1.Local имеет идентификатор и объект, тождество - это идентификатор threadid или greenlet, в этом примере _local.user = Пользователь () является эквивалентным для _local .___ storage __ [идентификатор текущего потока] ["user"] = User ()
Маленькое добавление ответа @Mark Hildreth.
Контекстный стек выглядит как {thread.get_ident(): []}
, где []
называется «стек», потому что используется только append
(push
), pop
и [-1]
(__getitem__(-1)
). Таким образом, стек контекста будет сохранять фактические данные для потока нити или зеленого.
current_app
, g
, request
, session
и т. Д. Является LocalProxy
объектом, который просто переопределяет специальные методы __getattr__
, __getitem__
, __call__
, __eq__
и т. д. и вернуть значение из верхнего стека контекста ([-1]
) по имени аргумента (например, current_app
, request
). LocalProxy
необходимо импортировать эти объекты один раз, и они не будут пропускать актуальность. Так что лучше просто импортировать request
, где бы вы ни находились в коде, вместо этого играйте с отправкой аргумента запроса до ваших функций и методов. Вы можете легко писать собственные расширения вместе с ним, но не забывайте, что легкомысленное использование может затруднить понимание кода.
Проведите время, чтобы понять https://github.com/mitsuhiko/werkzeug/ blob / master / werkzeug / local.py .
Итак, как заполняется оба стека? По запросу Flask
:
request_context
по средам (init map_adapter
, путь соответствия) request_context
создать app_context
, если он пропустил и нажал на стек контекста приложения, этот запрос был нажат для запроса сеанса инициализации контекста, если он пропустил