on
[Flask] 애플리케이션 팩토리 패턴과 순환참조
[Flask] 애플리케이션 팩토리 패턴과 순환참조
애플리케이션 팩토리 패턴이란?
애플리케이션 팩토리 패턴이란 순환참조 오류를 피하는 하나의 패턴이다. flask app을 전역변수로 사용한다면 프로젝트의 규모가 커져 여러개의 외부 모듈이 필요하게 된다면 추후 순환참조가 발생할 확률이 높아진다.
따라서 확장 가능한 서비스를 만들기 위해서는 flask 공식문서에서는 팩토리 패턴을 사용할 것을 권고하고 있다.
적용법
적용법은 간단하다 하나의 패키지 내부에 init.py 파일을 만들고 해당 파일에 create_app()메서드를 정의해주면 된다.
def create_app(): app = Flask(__name__) @app.route('/') def hello(): return 'hello' return app
팩토리 패턴을 사용하지 않을 때는 아래의 코드처럼 app을 전역 변수로 사용했다.
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run()
하지만 팩토리 패턴이 적용되고 나서는 create_app()이라는 메서드안으로 app = Flask()코드가 들어갔다. 이렇게 사용한 패턴을 애플리케이션 팩토리 패턴이라고 한다.
순환 참조란?
위의 팩토리 패턴이 순환참조를 피하기 위한 하나의 방법이라고 했다. 그러면 순환참조란 무엇이 왜 발생하는 것일까? 먼저 순환참조는 a는 b를 import 하고있고 b도 a를 import 하고 있는 상태를 의미한다. 코드를 통해 살펴보자
a.py
import b def func_a(): print('a func') return b.func_b() func_a()
b.py
import a def func_b(): print('b func') def func_c(): print('c fucn') return a.func_a()
이렇게 작성하고 각각을 실행해보자 그러면 a는 순환참조 에러가 발생하고 b는 정상적으로 동작한다. 이렇게 a.py에서 발생한 이슈를 순환 참조로 인한 오류라고 한다.
왜 그런것일까?
순환 참조를 이해하기 위해선 먼저 파이썬이 동작할 때 먼저 파이썬 가상머신이 해석할 수 있는 파이썬 바이트코드로 변환 되는데, 그때 결과물로 .pyc 파일이 생기는데 이 시점에서 Syntax Error 등의 에러가 발생한다. 또한 함수 본문과 클래스의 메소드 본문을 제외한 대부분의 코드를 byte code로 변환하는 시점에 실행한다.
따라서 a.py의 import b 부분을 byte code로 변환하는 과정에서 이미 b.py가 실행되는 것이고 b.py에서도 다시 import a하기 때문에 순환 참조가 발생한 것이다.
해결 방법
import가 되는 시점에 이미 b가 실행되는 것이 문제점이란 것을 알았기 때문에 해결 방법은 간단한다. 모듈을 임포트하는 시점을 단순시 runtime으로 옮기면 된다. 따라서 b.py의 import a를 func_c() 내부로 넣어주면 된다.
b.py
def func_b(): print('b func') def func_c(): import a print('c fucn') return a.func_a()
from http://bloowhale.tistory.com/111 by ccl(A) rewrite - 2021-10-20 15:00:24