BETTER WAY 85/ 패키지를 사용해 모듈을 체계화하고 안정적인 API를 제공하라
프로그램 코드베이스 크기가 늘어나면 코드 구조를 체계화하게 된다. 특히 모듈이 너무 많을 경우에는 다른 계층을 추가로 도입하게 되는데, 이를 위해 파이썬은 패키지package 를 제공한다. 이 패키지는 다른 모듈들을 포함하는 모듈이라고 할 수 있다.
패키지를 정의하기 위해서는 __init__.py
라는 이름의 빈 파일을 디렉터리에 추가해야 한다. (python3.3부터는 이 파일이 없어도 패키지로 인식되지만, 버전 호환을 위해 추가하는 것이 좋다.)
이미 __init__.py
가 있는 디렉터리가 있다면, 다른 파이썬 파일은 이를 상대적인 경로를 통해 import하면 된다.
패키지는 주로 두 가지 기능을 한다.
1. 이름 공간namespace
파일 이름은 같지만 서로 다른 경로의 모듈들을 정의할 수 있도록 해준다.
# main.py
from analysis.utils import inspect
from frontend.utils import inspect # import는 했지만 앞 줄의 inspect를 덮어쓰는 문제 발생
# main2.py
from analysis.utils import inspect as analysis_inspect
from frontend.utils import inspect as frontend_inspect # as를 통해 이름을 바꿔주면 해결된다
# main3.py
import analysis.utils
import frontend.utils
value = 33
if (analysis.utils.inspect(value) == (frontend.utils.inspect(value)):
print('인스펙션 결과가 같다')
# 귀찮지만 최상위 모듈부터 항상 붙여서 사용하는 방법도 있다
2. 안정적인 API 제공
오픈 소스 패키지와 같이 널리 사용될 API를 작성할 경우에는 변경되지 않는 안정적인 기능이 필요하다.
(단일 코드베이스나 팀 내에서 협업을 하는 경우라면 아래와 같은 방법까지는 필요하지 않을 것이다.)
그러려면 외부 사용자로부터 내부 코드 조직을 보호해야 한다. 그래야 외부 사용자의 코드를 깨지 않고 해당 패키지의 내부 모듈을 리팩터링 하고 개선할 수 있다.
__all__
attribute를 정의하면 사용자에게 노출할 범위를 제한할 수 있다. __all__
은 모듈에서 외부로 공개된 API로 export할 모든 속성이 있는 리스트이다.
예를 들어 from foof import *
를 실행하면 foo.__all__
에 있는 attribute만 import 된다.
# /mypackage/models.py
__all__ = ['Projectile']
class Projectile:
def __init__(self, mass, velocity):
self.mass = mass
self.velocity = velocity
# /mypackage/utils.py
from . models import Projectile
__all__ = ['simulate_collision']
def _dot_product(a, b):
...
def simulate_collision(a, b):
...
만약 mypackage 디렉터리에 있는 __init__.py
파일에 공개할 attribute만 import해 넣으면 mypackage의 외부 API를 명시적으로 지정할 수 있고, 일일이 각 모듈을 직접 import하지 않아도 된다.
# /mypackage/__init__.py
__all__ = []
from . models import *
__all__ += models.__all__
from . utils import *
__all__ += utils.__all__
# api_consumer.py
from mypackage import *
a = Projectile(1.5, 3)
b = Projectile(4, 1.7)
after_a, after_b = simulate_collision(a, b)
'공부하며 성장하기 > 파이썬 Python' 카테고리의 다른 글
List comprehension보다 for문이 빠른 경우 (0) | 2023.06.18 |
---|---|
[파이썬 코딩의 기술] 클래스 합성으로 복잡한 내포 관계 정리하기 (0) | 2022.07.02 |
🏆 2021 노마드 어워즈 후기 (0) | 2021.12.30 |
[파이썬 코딩의 기술] 02/ 협업의 미덕 (0) | 2021.07.04 |
[파이썬 코딩의 기술] 01/ 협업의 기초 (0) | 2021.07.04 |