갈루아의 반서재

장고 임포트(import) 순서 및 명시적 성격의 상대 임포트


1. PEP 8 에서 제안하는 임포트(import) 순서


pep 8은 임포트할 때 ㄷ음과 같은 순서로 그룹지을 것을 제안하고 있다.

1) 표준 라이브러리 임포트

2) 연관 외부 라이브러리 임포트

3) 로컬 애플리케이션 또는 라이브러리에 한정된 임포트


다음과 같이 임포트 문을 구성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 표준 라이브러리 임포트
from __future__ import absolute_import
from math import sqrt
from os.path import abspath
 
# 코어 장고 임포트
from django.db import models
from django.utils.translation import ugettext_lazy as _
 
# 서드 파티 앱 임포트
from django_extensions.db.models import TimeStampedModel
 
# 프로젝트 앱 임포트
from splits.models import BananaSplit
cs


2. 명시적 성격의 상대 임포트(EXPLICIT RELATIVE IMPORT) 이용하기


하드 코딩된 임포트 문들은 이식성 면에서나 재사용성 면에서 문제가 된다. 하드 코딩된 임포트 문을 이용했을 때 단지 앱의 이름을 바꿈으로서 모든 것이 해결되지는 않는다. 단순히 이름을 바꾸는 것 이외에도 모든 임포트 문을 일일이 확인해서 해당 임포트 문을 수정해야 하는 번거로운 작업이 요구된다.


1) 나쁜 예제

1
2
3
4
5
6
7
8
9
from django.views.generic import CreateView
 
# 'cones' 패키지에 하드 코딩된 암묵적 상대 임포트 
from cones.models import WaffleCone
from cones.forms import WaffleConeForm
from core.views import FoodMixin
class WaffleConeCreateView(FoodMixin, CreateView):
    model = WaffleCome
    form_class = WaffleConeForm
cs


2) 좋은 예제

1
2
3
4
5
6
7
8
9
10
from __future__ import absolute_import
from django.views.generic import CreateView
 
# 'cones' 패키지 상대 임포트
from .models import WaffleCone
from .forms import WaffleConeForm
from core.views import FoodMixin
class WaffleConeCreateView(FoodMixin, CreateView):
    model = WaffleCome
    form_class = WaffleConeForm
cs


코드

임포트 타입

용도

from core.views import FoodMixin

절대 임포트

외부에서 임포트해서 현재 앱에서 사용할 때

from .models import WaffleCone

명시적 상대

다른 모듈에서 임포트해서 현재 앱에서 이용할 때

from models import WaffleCone

암묵적 상대

종종 다른 모듈에서 임포트해서 현재 앱에서 이용할 때 쓰지만 좋은 방법은 아니다.


3. import * 는 피하자


1) 나쁜 예제

1
2
from django.forms import *
from django.db.models import *
cs

다른 파이썬 모듈의 이름공간들이 현재 우리가 작업하는 모듈의 이름 공간에 추가로 로딩되거나 기존 것 위에 덮여 로딩되는 일을 막기 위해서이다.

장고 폼 라이브러리와 장고 모델 라이브러리 둘 다 CharField 를 가지고 있다. 위의 예제의 경우  이 두 라이브러리를 암묵적으로 로딩함으로써 모델 라이브러리가 폼 버전의 클래스를 덮어 써버린다. 이러한 현상은 파이썬 내장 라이브러리와 다른 서드 파티 라이브러리들의 중요한 기능들을 덮어쓰는 원인이 되기도 한다.

같은 이름으로 두 개의 모듈을 임포트한다면 다음 경우와 같은 문제에 봉착하게 된다.

1
2
from django.forms import CharField
from django.db.models import CharField
cs

2)

2) 좋은 예제

1
2
from django import forms
from django.db import models 
cs


Two Scoops of Django (p.4~p.8) 요약정리