shapes 패키지 구조먼저 shapes라는 패키지의 구조를 살펴보겠습니다. shapes 패키지는 도형의 면적과 부피를 계산하는 함수들을 포함하는 패키지입니다. 이 패키지는 다음과 같은 구조를 가지고 있습니다:
tree
shapes/
__init__.py
area.py
volume.py
shapes/area.py: 도형의 면적을 계산하는 함수를 포함하고 있습니다.shapes/volume.py: 도형의 부피를 계산하는 함수를 포함하고 있습니다.shapes/__init__.py: 패키지 초기화 파일로, 패키지가 임포트될 때 실행되는 코드를 포함합니다.__init__.py 파일의 역할__init__.py 파일은 패키지의 초기화를 담당하는 파일입니다. 이 파일이 존재함으로써 Python은 해당 디렉토리가 패키지로 인식하게 됩니다. Python 3.3 이후로는 __init__.py 파일이 없어도 패키지로 인식되지만, 호환성과 명확성을 위해 여전히 이 파일을 포함하는 것이 권장됩니다.
__init__.py 파일 활용하기__init__.py 파일에서 임포트 사용하기__init__.py 파일을 활용하여 패키지 임포트 시 특정 모듈이나 객체를 자동으로 임포트할 수 있습니다. 예를 들어, shapes 패키지를 임포트할 때 area와 volume 모듈을 함께 임포트하고 싶다면 다음과 같이 설정할 수 있습니다:
# shapes/__init__.py
from shapes import area, volume
이렇게 하면 shapes 패키지를 임포트할 때 area와 volume 모듈도 함께 임포트됩니다. 이제 shapes.area.circle과 같은 방식으로 모듈에 접근할 수 있습니다.
또한, 모듈의 특정 함수나 객체를 직접 임포트할 수도 있습니다:
# shapes/__init__.py
from shapes.area import circle, square
from shapes.volume import sphere, cube
이 경우, shapes.circle과 같은 방식으로 함수를 호출할 수 있어, 모듈 이름을 생략하고 바로 함수에 접근할 수 있습니다.
__init__.py 파일에서 변수 정의하기__init__.py 파일에서 패키지 전체에서 공통으로 사용될 상수나 객체를 정의할 수 있습니다. 예를 들어, PI 값을 여러 모듈에서 사용해야 한다면 각 모듈에서 따로 정의하는 대신 __init__.py 파일에 정의하여 패키지 내에서 공유할 수 있습니다:
# shapes/__init__.py
PI = 3.14
이렇게 정의된 PI는 shapes.PI로 접근할 수 있으며, 패키지 내부의 다른 모듈에서도 from shapes import PI를 통해 사용할 수 있습니다.
__all__ 특수 변수란?__all__은 모듈이나 패키지에서 import *를 사용할 때 어떤 항목들이 임포트될지를 지정하는 특수 변수입니다. 이는 모듈과 패키지의 공개 인터페이스를 정의하는 역할을 합니다.
__all__ 변수 활용하기 - 모듈에서의 사용모듈에서 __all__ 변수를 정의하면, import *를 사용할 때 해당 모듈에서 임포트될 항목들을 제한할 수 있습니다. 예를 들어, shapes/area.py에서 다음과 같이 설정할 수 있습니다:
# shapes/area.py
__all__ = ['circle', 'square']
PI = 3.14
def circle(radius):
return PI * radius * radius
def square(length):
return length * length
이 경우, from shapes.area import *를 하면 circle과 square 함수만 임포트됩니다. 다른 변수나 함수는 임포트되지 않습니다.
__all__ 변수 활용하기 - 패키지에서의 사용패키지의 __init__.py 파일에서 __all__ 변수를 정의하면, from <package> import *를 사용할 때 어떤 모듈들이 임포트될지를 제어할 수 있습니다:
# shapes/__init__.py
__all__ = ['area', 'volume']
이 설정을 통해 from shapes import *를 하면 area와 volume 모듈만 임포트됩니다. 이처럼 __all__을 사용하면 패키지나 모듈의 공개 인터페이스를 명확하게 제어할 수 있습니다.
import *의 사용: import *는 코드 가독성을 떨어뜨리고, 예상치 못한 이름 충돌을 일으킬 수 있기 때문에, 일반적으로 권장되지 않습니다. 그러나 특정 상황에서 유용할 수 있으며, 이때 __all__을 정의해주면 예기치 않은 임포트 문제를 방지할 수 있습니다.__init__.py 파일을 잘 활용하면 패키지 구조를 명확하게 유지하면서 코드의 유지보수성을 높일 수 있습니다. 특히, 여러 모듈에서 공통으로 사용되는 상수나 객체를 중앙에서 관리함으로써, 코드의 중복을 줄이고 오류 발생 가능성을 낮출 수 있습니다.이러한 내용을 통해 패키지와 모듈을 보다 효율적으로 관리하고, 코드의 가독성과 유지보수성을 높일 수 있습니다.