Programing

언제 Flask.g을 사용해야합니까?

crosscheck 2020. 6. 10. 08:21
반응형

언제 Flask.g을 사용해야합니까?


I g 나를 만든 플라스크 0.10에 응용 프로그램 컨텍스트에 요청 문맥에서 이동은,의 용도에 대해 혼란스러워 g.

Flask 0.9의 이해는 다음과 같습니다.

  • g 요청 컨텍스트에 존재합니다. 즉, 요청이 시작될 때 새로 생성되고 끝날 때까지 사용 가능
  • g내가 요청의 기간 동안 관련 물건을 넣을 수있는 "요청 칠판"로 사용하기위한 것입니다 (즉, 요청의 시작 부분에 플래그를 설정하고부터 가능, 마지막에 처리 before_request/의 after_request쌍)
  • 요청 수준 상태를 유지하는 것 외에도 g데이터베이스 연결을 유지하는 등 리소스 관리에 사용할 수 있으며 사용해야합니다.

Flask 0.10에서 더 이상 해당되지 않는 문장은 무엇입니까? 누군가 변경 이유논의하는 리소스를 알려줄 수 있습니까? Flask 0.10에서 "요청 칠판"으로 무엇을 사용해야합니까? 내 자신의 앱 / 확장자 별 스레드 로컬 프록시를 작성하여 컨텍스트 스택으로 푸시해야 before_request합니까? 내 응용 프로그램이 오랜 기간 동안 (요청이 아닌) 지속되어 리소스가 해제되지 않는 경우 응용 프로그램 컨텍스트에서 리소스 관리의 요점은 무엇입니까?


Markus연결된 Advanced Flask Patternsg 는 0.10의 일부 변경 사항을 설명합니다 .

  • g 이제 응용 프로그램 컨텍스트에 있습니다.
  • 모든 요청은 새로운 애플리케이션 컨텍스트를 푸시 하고 이전 컨텍스트 를 삭제하므로 g코드를 변경하지 않고도 요청 당 플래그를 설정하는 데 계속 사용할 수 있습니다.
  • 응용 프로그램 컨텍스트 가 호출 된 팝업 teardown_request됩니다. (아르 민의 발표는 DB 연결을 만드는 등의 일을하는 작업이기 때문입니다 설명 설치 요청에 대한 환경 및 내부 처리해서는 안 before_request하고 after_request)

이 글의 정보에 대한 부록으로서 : flask.g저 역시 그 동작에 약간 혼란 스러웠지만 , 빠른 테스트를 통해이를 명확히하는 데 도움이되었습니다. 내가 시도한 것은 다음과 같습니다.

from flask import Flask, g
app = Flask(__name__)

with app.app_context():
    print('in app context, before first request context')
    print('setting g.foo to abc')
    g.foo = 'abc'
    print('g.foo should be abc, is: {0}'.format(g.foo))

with app.test_request_context():
    print('in first request context')
    print('g.foo should be abc, is: {0}'.format(g.foo))
    print('setting g.foo to xyz')
    g.foo = 'xyz'
    print('g.foo should be xyz, is: {0}'.format(g.foo))

print('in app context, after first request context')
print('g.foo should be abc, is: {0}'.format(g.foo))

with app.test_request_context():
    print('in second request context')
    print('g.foo should be abc, is: {0}'.format(g.foo))
    print('setting g.foo to pqr')
    g.foo = 'pqr'
    print('g.foo should be pqr, is: {0}'.format(g.foo))

print('in app context, after second request context')
print('g.foo should be abc, is: {0}'.format(g.foo))

그리고 그 결과는 다음과 같습니다.

in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc  

in first request context
g.foo should be abc, is: abc
setting g.foo to xyz
g.foo should be xyz, is: xyz  

in app context, after first request context
g.foo should be abc, is: xyz  

in second request context
g.foo should be abc, is: xyz
setting g.foo to pqr
g.foo should be pqr, is: pqr  

in app context, after second request context
g.foo should be abc, is: pqr

As theY4Kman said above, "Every request pushes a new application context". And as the Flask docs say, the application context "will not be shared between requests". Now, what hasn't been explicitly stated (although I guess it's implied from these statements), and what my testing clearly shows, is that you should never explicitly create multiple request contexts nested inside one application context, because flask.g (and co) doesn't have any magic whereby it functions in the two different "levels" of context, with different states existing independently at the application and request levels.

The reality is that "application context" is potentially quite a misleading name, because app.app_context() is a per-request context, exactly the same as the "request context". Think of it as a "request context lite", only required in the case where you need some of the variables that normally require a request context, but you don't need access to any request object (e.g. when running batch DB operations in a shell script). If you try and extend the application context to encompass more than one request context, you're asking for trouble. So, rather than my test above, you should instead write code like this with Flask's contexts:

from flask import Flask, g
app = Flask(__name__)

with app.app_context():
    print('in app context, before first request context')
    print('setting g.foo to abc')
    g.foo = 'abc'
    print('g.foo should be abc, is: {0}'.format(g.foo))

with app.test_request_context():
    print('in first request context')
    print('g.foo should be None, is: {0}'.format(g.get('foo')))
    print('setting g.foo to xyz')
    g.foo = 'xyz'
    print('g.foo should be xyz, is: {0}'.format(g.foo))

with app.test_request_context():
    print('in second request context')
    print('g.foo should be None, is: {0}'.format(g.get('foo')))
    print('setting g.foo to pqr')
    g.foo = 'pqr'
    print('g.foo should be pqr, is: {0}'.format(g.foo))

Which will give the expected results:

in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc
in first request context
g.foo should be None, is: None
setting g.foo to xyz
g.foo should be xyz, is: xyz
in second request context
g.foo should be None, is: None
setting g.foo to pqr
g.foo should be pqr, is: pqr

참고URL : https://stackoverflow.com/questions/15083967/when-should-flask-g-be-used

반응형