0부터 Flask4 배우기 - 컨텍스트 요청 및 적용

8329 단어
컨텍스트란?
프로그램마다 많은 외부 변수가 있다.Add와 같은 간단한 함수만 외부 변수가 없습니다.일단 프로그램에 외부 변수가 생기면, 이 프로그램은 완전하지 않아서 독립적으로 실행할 수 없다.너는 그들을 운행시키기 위해서 모든 외부 변수에 값을 하나씩 써야 한다.이 값들의 집합을 상하문이라고 부른다.
상하문 작용역?
예를 들어: 사용자가 이동해야 할 URL을 되돌려 주는 응용 함수가 있습니다.URL의next 매개 변수나 HTTP referrer, 또는 색인 페이지로 항상 이동한다고 생각하십시오:
from flask import request, url_for

def redirect_url():
    return request.args.get('next') or \
           request.referrer or \
           url_for('index')

우리는 요청한 대상을 방문했지만, 프로그램을 실행할 때:
>>> redirect_url()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'NoneType' object has no attribute 'request'

현재 방문할 수 있는 요청이 없기 때문에 이 오류가 발생했습니다.그래서 우리는 요청을 만들어 현재의 상하문에 귀속시켜야 한다.test_request_context 메서드가 RequestContext를 만들었습니다.
>>> ctx = app.test_request_context('/?next=http://example.com/')

이 상하문을 두 가지 방식으로 사용할 수 있습니다: with 성명을 사용하거나push()와pop() 방법을 호출할 수 있습니다.
>>> ctx.push()

그런 다음 요청 객체를 사용합니다.
>>> redirect_url()
u'http://example.com/'

pop을 호출할 때까지:
>>> ctx.pop()

위아래 문장을 내부에서 하나의 창고로 유지해 달라고 요청하기 때문에, 너는 여러 번 창고를 압수하고 출고할 수 있다.이것은 내부의 방향을 바꾸는 것과 같은 것을 실현할 때 매우 편리하다.
상하문은 어떻게 작동합니까?
이 코드를 살펴보겠습니다.
def wsgi_app(self, environ):
    with self.request_context(environ):
        try:
            response = self.full_dispatch_request()
        except Exception, e:
            response = self.make_response(self.handle_exception(e))
        return response(environ, start_response)

request_context () 방법은 새 RequestContext 대상을 되돌려주고 with 성명과 결합하여 위아래 문장을 연결합니다.같은 라인에서 호출된 모든 것들은 with 성명이 끝날 때까지 전역 요청 변수flask에 접근할 수 있습니다.request 및 기타).
컨텍스트 내부 작업을 스택처럼 요청합니다.스택 상단은 현재 활성 요청입니다.push는 위아래 문장을 창고 위에 추가하고 pop은 창고에서 옮깁니다.출고 시 적용되는teardownrequest 함수도 실행됩니다.
또 하나 주의해야 할 것은 위아래 문장이 창고에 눌려 들어갈 때 현재 응용되고 있는 응용 프로그램의 위아래 문장이 없으면 자동으로 응용 프로그램의 위아래 문장을 만들 수 있다는 것이다.
컨텍스트 요청
Flask에서 실제 처리 요청을 적용할 때 wsgiapp(environ, start response)가 호출됩니다.이 함수는 다음과 같이 실행됩니다.
def wsgi_app(environ, start_response):
    with self.request_context(environ):
        ...

Flask에서 요청을 처리할 때 응용 프로그램은 요청 컨텍스트 객체를 생성합니다.모든 요청의 처리 과정은 이 상하문 대상에서 진행될 것이다.이것은 요청의 처리 과정이 방해되지 않도록 보장한다.세그먼트 코드 보기:
# Flask v0.1
class _RequestContext(object):
    """The request context contains all request relevant information.  It is
    created at the beginning of the request and pushed to the
    `_request_ctx_stack` and removed at the end of it.  It will create the
    URL adapter and request object for the WSGI environment provided.
    """
    def __init__(self, app, environ):
        self.app = app
        self.url_adapter = app.url_map.bind_to_environ(environ)
        self.request = app.request_class(environ)
        self.session = app.open_session(self.request)
        self.g = _RequestGlobals()
        self.flashes = None
    def __enter__(self):
        _request_ctx_stack.push(self)
    def __exit__(self, exc_type, exc_value, tb):
        # do not pop the request stack if we are in debug mode and an
        # exception happened.  This will allow the debugger to still
        # access the request object in the interactive shell.
        if tb is None or not self.app.debug:
            _request_ctx_stack.pop()

근거RequestContext 컨텍스트 객체의 정의는 객체를 구성할 때 Flask 응용 프로그램과 관련된 몇 가지 속성을 추가한 것을 알 수 있습니다.
app ——      app      Flask  ;

url_adapter ——      url_adapter     Flask    Map       MapAdapter  ,          URL Map    URL      ;

request ——      request     Request      ,       ;

session ——      session           ;

g ——      g             。

flashes ——       。
def wsgi_app(self, environ, start_response):
    with self.request_context(environ):
        # with       `response`  
        ...
    return response(environ, start_response)

요청 상하문 대상은 요청 처리와 관련된 정보를 포함한다.그리고 Flask는 werkzeug에 따라.local 모듈에서 구현된 데이터 구조인 LocalStack은 '요청 상하문' 대상을 저장하는 데 사용됩니다.
  • LocalStack 상세 정보
  • >>> from werkzeug.local import LocalStack
    >>> import threading
    
    #     `LocalStack`  
    >>> local_stack = LocalStack()
    #   local_stack      
    >>> local_stack._local.__storage__
    {}
    
    #       ,       `LocalStack`     
    >>> def worker(i):
            local_stack.push(i)
    
    #   3       `worker`
    >>> for i in range(3):
            t = threading.Thread(target=worker, args=(i,))
            t.start()
    
    #     local_stack      
    >>> local_stack._local.__storage__
    {: {'stack': [2]},
     : {'stack': [1]},
     : {'stack': [0]}
    }
    

    위의 예에서 보듯이 Local Stack에 저장된 정보는 사전 형식으로 존재한다. 키는 라인/협정의 표지 수치이고 값도 사전 형식이다.한 라인/협정에서 대상push를 Local Stack 창고에 넣을 때마다 이전의'키-값'쌍이 형성된다.이러한 구조는 라인/협정의 격리를 잘 실현했고 모든 라인/협정은 자신의 라인/협정의 표지 수치에 따라 창고 구조에 저장된 값을 확정한다.
    LocalStack에서는 push, pop, top 등의 방법도 구현했다.그 중에서 top 방법은 창고 꼭대기의 원소를 영원히 가리킨다.창고 꼭대기의 원소는 현재 스레드/협정에서 마지막으로 창고에 밀려든 원소를 가리킨다. 즉localstack._local.stack-1. local 모듈
    응용 컨텍스트
    Flask 배후의 디자인 이념 중 하나는 코드가 실행할 때 두 가지 다른'상태'(states)에 있다는 것이다.Flask 객체가 인스턴스화되면 모듈 계층에서 응용 프로비저닝 상태가 암시적으로 적용됩니다.첫 번째 요청이 이 상태에 이르러서야 은근히 끝났다.응용 프로그램이 이 상태에 있을 때 다음과 같은 가설이 성립되었다고 생각할 수 있다.
  • 프로그래머는 응용 대상을 안전하게 수정할 수 있다
  • 아직 처리되지 않은 요청
  • 응용 대상을 가리키는 인용을 가지고 수정해야 합니다.새로 만들거나 수정 중인 응용 대상을 가리키는 신기한 프록시 변수가 없을 것이다.
  • 반대로 두 번째 상태가 되면 요청을 처리할 때 몇 가지 다른 규칙이 있습니다.
  • 요청이 활성화되면 상하문의 로컬 대상flask.request 및 기타 객체 등) 현재 요청
  • 을 가리킵니다.
  • 당신은 언제든지 코드를 사용하여 이 대상과 통신할 수 있습니다
  • 여기에는 세 번째 상황이 하나 있는데, 약간의 차이가 있다.때때로, 활성 요청이 없어도, 유사한 요청 처리 방식으로 응용 프로그램과 상호작용을 하고 있습니다.인터랙티브 파이썬 셸을 사용해서 응용 프로그램과 인터랙티브를 하거나 명령행으로 사용하는 상황을 상상해 보세요.current_app 상하문 로컬 변수는 상하문 구동을 응용합니다.
    컨텍스트 역할 적용
    응용 상하문이 존재하는 주요 원인은 과거에 요청 상하문에 한 무더기의 함수가 추가되었지만 좋은 해결 방안이 없었기 때문이다.Flask 디자인의 기둥 중 하나는 Python 프로세스에서 여러 개의 응용 프로그램을 가질 수 있기 때문이다.
    그러면 코드는 어떻게'정확한'응용을 찾습니까?과거에는 응용 프로그램을 현저하게 전달하는 것을 추천했지만 이런 이념으로 디자인되지 않은 라이브러리를 사용할 때 문제가 발생할 수 있다.
    상술한 문제를 해결하는 데 자주 사용하는 방법은 뒤에 언급할currentapp 프록시 대상입니다. 현재 요청한 응용 프로그램의 인용에 귀속됩니다.어쨌든 요청이 없을 때 이런 요청 상하문을 만드는 것은 불필요한 비싼 작업이기 때문에 응용 상하문이 도입되었다.
    응용 프로그램 컨텍스트 작성
    응용 프로그램 상하문을 만드는 두 가지 방법이 있습니다.첫 번째는 스텔스입니다. 요청한 상하문이 압축될 때 필요할 때 응용 프로그램 상하문이 함께 만들어집니다.이 때문에, 네가 그것을 필요로 하지 않는 한, 너는 상하 문장의 존재를 무시할 수 있다.두 번째는 앱을 현시적으로 호출하는context () 방법:
    from flask import Flask, current_app
    
    app = Flask(__name__)
    with app.app_context():
        # within this block, current_app points to app.
        print current_app.name
    

    SERVERNAME 시 URL 에 컨텍스트 적용for () 함수.이것은 요청이 없을 때 URL을 생성할 수 있도록 합니다.
    컨텍스트 로컬 변수 적용
    적용 컨텍스트는 필요한 경우 작성되고 제거됩니다.그것은 온라인 거리 사이를 이동하지 않을 뿐만 아니라, 서로 다른 요청 사이도 공유하지 않을 것이다.그렇기 때문에 데이터베이스 연결 정보나 다른 것을 저장하기에 가장 좋은 위치다.내부 스택 객체는 flask. 라고 합니다.app_ctx_stack.확장은 최상층에 추가 정보를 자유롭게 저장할 수 있으며, flask가 아닌 충분한 독특한 이름으로 그곳에 정보를 저장할 수 있다고 상상해 보세요.g 대상에서 flask.g는 사용자에게 남겨진 코드용입니다.
    컨텍스트 사용
    위아래 문장의 전형적인 응용 장면은 우리가 요청이 발생하기 전이나 사용해야 할 자원을 캐시하는 데 쓰인다.예를 들어 데이터베이스 연결.우리가 상하문에서 물건을 저장할 때 유일한 이름을 선택해야 한다. 이것은 상하문이 Flask 응용 프로그램과 확장에 공유되기 때문이다.
    가장 흔히 볼 수 있는 응용은 자원 관리를 다음과 같은 두 부분으로 나누는 것이다.
  • 상하문에 캐시된 스텔스 자원
  • 상하문이 소각될 때 기초자원을 재분배
  • 통상적으로 말하면, 이것은 get 이 있을 것이다X () 함수는 자원 X를 생성합니다. 만약 그것이 존재하지 않는다면.존재하면 바로 돌려보내.그리고 또 하나의 테드윈이 있어요X()의 콜백 함수는 자원 X를 제거하는 데 사용됩니다.
    다음은 우리가 방금 언급한 연결 데이터베이스의 예이다.
    import sqlite3
    from flask import g
    
    def get_db():
        db = getattr(g, '_database', None)
        if db is None:
            db = g._database = connect_to_database()
        return db
    
    @app.teardown_appcontext
    def teardown_db(exception):
        db = getattr(g, '_database', None)
        if db is not None:
            db.close()
    

    getdb () 이 함수가 처음 호출되었을 때 데이터베이스 연결이 구축되었습니다.은밀하게 보이기 위해 LocalProxy 클래스를 사용할 수 있습니다.
    from werkzeug.local import LocalProxydb = LocalProxy(get_db)
    

    이렇게 하면 사용자는db에 직접 접근하여 데이터 핸들을 얻을 수 있다.db는 이미 내부에서 get 에 대한 완성을 마쳤다db ()의 호출.

    좋은 웹페이지 즐겨찾기