1. Start executing the App.run () in manage.py first
def run (self, host=none, Port=none, Debug=none, * *options) : fromimport Run_simple try: #Run_simple is a Werkzeug provided method that executes the third argument self () Run_simple (host, Port, self, **options)
Executes the app (), object () that represents the __call__ method of the calling object
def __call__ (self, Environ, start_response): return Self.wsgi_app (environ, start_response)
The App.wsgi_app method is also called
defWsgi_app (self, Environ, start_response):#1.
CTX =Self.request_context (environ)
#Self.request_context #2. Ctx.push ()
Try: Try:
#3.Response =self.full_dispatch_request ()exceptException as E:error=e Response=self.handle_exception (e)except: Error= Sys.exc_info () [1] Raise returnresponse (environ, start_response)finally: ifSelf.should_ignore_error (Error): Error=None Ctx.auto_pop (Error)
1th Step: Execute the App. Request_context Method, the information of the request is passed in.
def Request_context (self, environ): return RequestContext (self, environ)
Returns an instance object of the RequestContext class
def __init__ (self, app, environ, request=None): = App if is None: =
#App.request_class = Request = request = None
Notice in the init construction method that the app also calls the Request_class method, which is the request instance an object,
So far we know:
CTX is a RequestContext object, which encapsulates two main properties, one is the object of self.request = Request instance, and the request object encapsulates all the data requested in.
The other one is self.session = None .
2nd step: Execute the ctx.push () method
Because CTX is the object of the RequestContext class, we're going to find the push method in the RequestContext class.
defpush (self): #1. App_ctx=_app_ctx_stack.topifApp_ctx isNoneorApp_ctx.app! =Self.app:app_ctx=Self.app.app_context ()
# Self.app.app_context = app.app_context = AppContext (APP) App_ctx.push ()
#2.
_request_ctx_stack.push (self)
#_request_ctx_stack = Localstack ()
#3.
Self.session = Self.app.open_session (self.request)
When #判断没有 Secret_key:
If Self.session is None:
Self.session = Self.app.make_null_session ()
#raise RuntimeError (' The session is unavailable because no secret ' key was set.)
1th step: To the _app_ctx_stack this stack to take the last data, if not fetch or fetch the app is not the current app, call the app. the App_context () method is a new instance of an App object that executes the app. push () method (in this again, because the app is a AppContext object, first go to the AppContext class to find the Push method),
def push (self): _app_ctx_stack.push (self) #把新创建的app对象添加到了_app_ctx_stack in this stack appcontext_ Pushed.send (Self.app) #在这里遇到了第一个信号, executes when requesting app context push
2nd step:Call the Push method for an object of the Localstack class
def push (self, obj): ' Stack' , None) #self. _local = local ()
#第一次的时候rv肯定是None if is None: = RV = [] #Local对象. stack = RV = [] executes the __setattr__ method of the object rv.append (obj) return RV
Try: fromGreenletImportGetCurrent as Get_identexceptImporterror:Try: fromThreadImportget_identexceptImporterror: from_threadImportget_identclassLocal (object):
def __init__ (self):
Object.__setattr__ (self, ' __storage__ ', {}) #这里为什么用object.__setattr__ instead of using self directly. __storage__={}
Object.__setattr__ (self, ' __ident_func__ ', get_ident) #如果用self的方式设置属性, will trigger the self's __setattr__ method, will be infinite loop
def __setattr__(self, Name, value): Ident= self.__ident_func__() Storage= self.__storage__ Try: Storage[ident][name]=valueexceptKeyerror:storage[ident]= {Name:value}
python-flask-Source Flow