본문 바로가기
Python/study

__init__

by 르면가게 2025. 2. 19.

 __init__.py의 역할과 사용법

__init__.py 파일은 Python 패키지를 식별하고 초기화하는 역할을 합니다.
이 파일이 있는 폴더는 Python에서 패키지로 인식되며, 모듈을 불러올 수 있습니다.


1️⃣ __init__.py의 기본 역할

  1. 패키지(모듈 폴더)로 인식
    • __init__.py가 존재하면, 해당 디렉터리는 Python 패키지로 인식됨.
    • import package_name을 사용하여 패키지를 불러올 수 있음.
  2. 패키지 초기화 코드 실행
    • __init__.py 내부에 코드를 작성하면 패키지가 처음 import될 때 실행됨.
    • 예를 들어 전역 변수 설정, 서브모듈 자동 로드, 로깅 설정 등을 할 수 있음.
  3. 패키지에서 특정 모듈을 공개
    • __all__ 리스트를 정의하여 from package import * 시 어떤 모듈을 공개할지 제어 가능.

2️⃣ __init__.py 예제

📁 프로젝트 폴더 구조

project/
│── main.py
│── mypackage/
│   │── __init__.py
│   │── module1.py
│   │── module2.py

mypackage/__init__.py

print("mypackage 패키지가 로드되었습니다!")

# 패키지 초기화 코드
VERSION = "1.0"

# 특정 모듈을 자동으로 import
from .module1 import function1
from .module2 import function2

# 패키지에서 공개할 모듈을 제한
__all__ = ["function1", "function2"]

📜 mypackage/module1.py

def function1():
    return "Hello from module1!"

📜 mypackage/module2.py

def function2():
    return "Hello from module2!"

📜 main.py에서 사용

import mypackage  # __init__.py 실행됨

print(mypackage.VERSION)  # "1.0"
print(mypackage.function1())  # "Hello from module1!"
print(mypackage.function2())  # "Hello from module2!"

실행하면 다음과 같은 출력이 나옴:

mypackage 패키지가 로드되었습니다!
1.0
Hello from module1!
Hello from module2!

__init__.py의 주요 기능

기능 설명
패키지 인식 __init__.py가 있는 폴더는 패키지로 인식됨
초기화 코드 실행 패키지가 import될 때, 내부 코드가 실행됨
전역 변수 설정 패키지 버전, 환경설정 등을 정의할 수 있음
자동 import 특정 모듈을 __init__.py에서 불러와 mypackage.function1()처럼 바로 사용 가능
모듈 제한 __all__을 설정하여 from mypackage import * 시 공개할 모듈을 제한

 

__init__.py 활용 예제

1. 패키지 초기화 코드 실행

# mypackage/__init__.py
print("mypackage가 로드됨!")

 

# main.py
import mypackage  # "mypackage가 로드됨!" 출력됨

 

2. 자동 모듈 import

# mypackage/__init__.py
from .module1 import function1
from .module2 import function2
# main.py
import mypackage
mypackage.function1()  # 바로 사용 가능

 

3. __all__로 모듈 제한

# mypackage/__init__.py
__all__ = ["module1"]  # module2는 import되지 않음
from mypackage import *  # module1만 사용 가능

 

정리

  • __init__.py가 있는 폴더는 패키지로 인식됨.
  • 패키지가 import될 때 초기화 코드 실행 가능.
  • 자동 import 설정하여 편리하게 모듈 사용 가능.
  • __all__ 설정으로 공개할 모듈을 제한할 수 있음.

 

Python 3.5부터 __init__.py가 없어도 패키지가 동작하는 이유

맞습니다! Python 3.3부터 __init__.py 없이도 폴더를 패키지로 인식할 수 있습니다.
이는 "네임스페이스 패키지(Namespace Packages)" 개념이 도입되었기 때문입니다.


1️⃣ __init__.py 없이도 패키지가 되는 이유

  • Python 3.2 이하
    • __init__.py가 반드시 있어야 폴더가 패키지로 인식됨.
  • Python 3.3 이상 (특히 3.5~)
    • __init__.py가 없어도 패키지로 인식되며, 이를 **"네임스페이스 패키지"**라고 부름.

✅ 즉, Python 3.5 이후부터는 __init__.py 없이도 import가 가능합니다.


2️⃣ __init__.py 없는 경우 vs 있는 경우

구분 __init__.py 없음 (네임스페이스 패키지) __init__.py 있음 (일반 패키지)
필수 여부 Python 3.3 이상에서는 없어도 됨 Python 3.2 이하에서는 필수
패키지 인식 여부 가능 (동적 패키지 생성) 가능 (전통적인 방식)
초기화 코드 실행 ❌ 실행 불가 ✅ 가능
자동 import 설정 ❌ 불가능 (from package import * 제한) ✅ 가능 (__all__ 사용 가능)
전역 변수 설정 ❌ 불가능 ✅ 가능

 


3️⃣ __init__.py 없는 네임스페이스 패키지 예제

📁 폴더 구조

project/
│── main.py
│── mypackage/  # __init__.py 없음 (네임스페이스 패키지)
│   │── module1.py
│   │── module2.py

📜 mypackage/module1.py

def hello():
    return "Hello from module1!"

📜 main.py

import mypackage.module1  # __init__.py 없이도 가능

print(mypackage.module1.hello())  # "Hello from module1!"

✅ __init__.py 없이도 mypackage.module1을 정상적으로 import 가능.


4️⃣ 언제 __init__.py를 사용해야 할까?

__init__.py 없이도 패키지를 사용할 수 있지만, 여전히 __init__.py를 사용해야 하는 경우가 많습니다.

✅ __init__.py가 필요한 경우

  1. 패키지 초기화 코드 실행
    • import mypackage 하면 "mypackage가 로드되었습니다!" 출력됨.
  2. # mypackage/__init__.py print("mypackage가 로드되었습니다!")
  3. 자동 모듈 import
    # main.py
    import mypackage
    print(mypackage.hello())  # __init__.py 없으면 불가능!
    
  4. # mypackage/__init__.py from .module1 import hello
  5. 전역 변수 설정 (예: 버전 정보)
  6. # mypackage/__init__.py VERSION = "1.0"
  7. 모듈 제한 (__all__ 설정)
  8. # mypackage/__init__.py __all__ = ["module1"]

정리

  • Python 3.5 이후에는 __init__.py 없이도 패키지를 인식할 수 있음.
  • 하지만, 초기화 코드 실행, 자동 import, 전역 변수 설정, __all__ 사용 등에는 여전히 필요.
  • 즉, 특별한 이유가 없다면 __init__.py를 유지하는 것이 좋음! 🚀

'Python > study' 카테고리의 다른 글

@wrap  (0) 2025.01.15
unittest 모듈  (0) 2024.12.08
@staticmethod  (0) 2024.12.08
ast.literal_eval()  (0) 2024.12.08
__str__와 __repr__  (0) 2024.12.08