제로베이스 데이터 파트타임 스쿨 학습 일지 [25.03.30]

[강의 요약]

[Ch 03. 파이썬 중급] 강의 수강

12_실행(메인) 파일 (01)부터 16_자주 사용하는 외부 모듈까지 강의 수강하였음

정리하는데 양이 정말... 많았다.

최소 3 회독은 해야 누가 물어봐도 대답할 수 있을 것 같음

나는 혼자 공부해서 gpt와 질의응답시간을 가지면서 복습한다. 나름 괜찮음!

자격증 시험이 얼마 남지 않아서 04.05까지는 최소한의 강의를 수강할 예정

 

 

 

[실행(메인) 파일]

  • __name__ 전역변수
    • 특별한 전역변수
    • 이 파일이 직접 실행된 건지, 아니면 다른 데서 불러온 건지 구분할 수 있게 해 준다.
  • 내가 직접 실행한 파일
    • __main__
  • 다른 파일에서 import 한 경우
    • '파일 이름' (문자열)
  • 왜 필요할까?
    • 어떤 파일은 '재사용되는 모듈'을 담아두고, 다른 파일에서는 그걸 불러서 사용하는 경우가 많음
    • 근데 그 모듈 파일 안에 테스트 코드가 있다면, import 할 때마다 실행되면 곤란함
    • 그래서 __name__을 이용해서 이 파일이 직접 실행될 때만 테스트 코드를 실행하게 만들 수 있음

 

 

▶ 계산기처럼 4가지 연산을 분리해서 파일로 만든 모듈

  • addModule.py
def add(n1, n2):
    return n1 + n2

# 직접 실행 시에만 실행됨
if __name__ == '__main__':
    result = add(10, 20)
    print(f'Add result: {result}')
    print(f'__name__: {__name__}')

 

  • subModule.py
def sub(n1, n2):
    return n1 - n2

if __name__ == '__main__':
    result = sub(10, 20)
    print(f'Sub result: {result}')
    print(f'__name__: {__name__}')

 

  • mulModule.py
def mul(n1, n2):
    return n1 * n2

if __name__ == '__main__':
    result = mul(10, 20)
    print(f'Mul result: {result}')
    print(f'__name__: {__name__}')

 

  • divModule.py
def div(n1, n2):
    return n1 / n2

if __name__ == '__main__':
    result = div(10, 20)
    print(f'Div result: {result}')
    print(f'__name__: {__name__}')

 

 

메인 실행 파일 : module.py

import addModule as a
import subModule as s
import mulModule as m
import divModule as d

if __name__ == '__main__':
    print(f'a.add(10, 20): {a.add(10, 20)}')
    print(f's.sub(10, 20): {s.sub(10, 20)}')
    print(f'm.mul(10, 20): {m.mul(10, 20)}')
    print(f'd.div(10, 20): {d.div(10, 20)}')
    print(f'__name__: {__name__}')

 

 

→ addModule.py를 실행하면?

Add result: 30
__name__: __main__

 

→module.py를 실행하면?

a.add(10, 20): 30
s.sub(10, 20): -10
m.mul(10, 20): 200
d.div(10, 20): 0.5
__name__: __main__

★ 설명 ★

실행했을 때 addModule.py의 __name__은 addModule이므로

테스트 코드는 실행되지 않는다. (import 했을 뿐이니까)

코드 실행 흐름 이해를 위한 도식

 

 

실습 코드

  • 모듈 파일: unitConversion.py
def cmToMm(n):
    return round(n * 10, 3)

def cmToInch(n):
    return round(n * 0.393, 3)

def cmToM(n):
    return round(n * 0.01, 3)

def cmToFt(n):
    return round(n * 0.032, 3)

# 테스트 코드
if __name__ == '__main__':
    print(f'10cm: {cmToMm(10)}mm')
    print(f'10cm: {cmToInch(10)}inch')
    print(f'10cm: {cmToM(10)}m')
    print(f'10cm: {cmToFt(10)}ft')

★ 설명 ★

이 모듈에는 cm를 다양한 단위로 바꾸는 함수들이 정의되어 있다.

여러 함수가 있는데 각 함수는 cm 값을 mm, inch, m, ft로 바꿔주는 역할을 한다.

그리고 마지막에 테스트 코드가 있는데, 이건 모듈이 단독 실행될 때만 실행된다.

 

unitConversion.py를 직접 실행하면 출력되고

다른 파일에서 import 할 경우에는 이 부분은 실행되지 않는다.

 

이런 방식은 모듈을 기능 단위로 분리해서 재사용하고

__name__ == '__main__'을 통해 모듈이 직접 실행될 때만 테스트 코드가 실행되도록 한다.

 

 

 

  • 실행 파일: main.py
import unitConversion as uc

if __name__ == '__main__':
    inputNumber = int(input('길이(cm) 입력: '))

    returnValue = uc.cmToMm(inputNumber)
    print(f'{inputNumber}cm = {returnValue}mm')

    returnValue = uc.cmToInch(inputNumber)
    print(f'{inputNumber}cm = {returnValue}inch')

    returnValue = uc.cmToM(inputNumber)
    print(f'{inputNumber}cm = {returnValue}m')

    returnValue = uc.cmToFt(inputNumber)
    print(f'{inputNumber}cm = {returnValue}ft')

★ 설명 ★

이 파일에서는 unitConversion 모듈을 uc라고 불러오고

사용자로부터 cm 값을 입력받아 다양한 단위로 변환해 주는 과정을 보여준다.

 

 

 

  • unitConversion.py 모듈 파일 직접 실행 결과
10cm: 100.0mm
10cm: 3.93inch
10cm: 0.1m
10cm: 0.32ft

 

  • main.py 실행 결과
길이(cm) 입력: 20
20cm = 200.0mm
20cm = 7.86inch
20cm = 0.2m
20cm = 0.64ft

 

 

 

 

[패키지]

  • 패키지가 뭘까?
    • 여러 모듈(.py 파일)을 묶어 놓은 폴더 단위의 묶음
    • 계산 기능처럼 관련 있는 파일들을 구조화할 때 사용함
    • __init__.py 파일은 '여기는 패키지다~' 라는 표시 (비워둬도 된다)
      • 이 파일이 들어있어야 이 폴더가 패키지라고 파이썬이 인식함

패키지 예시

 

실제로 사용한 패키지 구조

  • 아니... __init__.py 없이도 패키지가 동작하는데 이게 무슨 일이지?
    • 예전 파이썬(3.2 이하)에서는 __init__.py 없으면 import 자체가 안 됐음
  • 지금은?
    • 파이썬 3.3부터는 암시적 네임스페이스 패키지(Implicit Namespace Package) 개념이 도입
    • 즉, __init__.py 없이도 패키지를 import 할 수 있도록 바뀐 것
  • 그러면 __init__.py는 이제 안 써도 괜찮은가?
    • No
    • 지금은 없어도 import는 가능하지만, __init__.py는 여전히 중요한 역할을 한다.

__init__.py 가 필요한 상황시

  • 실전에서는 어떻게 사용할까?
    • 실습/테스트용이면 없어도 괜찮음
    • 프로젝트용 패키지를 만든다면 __init__.py를 비워서라도 꼭 넣어두는 게 좋다
# 예시: __init__.py 내부
print("Calculator 패키지가 import되었습니다!")

 

 

▶ 각 모듈 코드(CalculatorForInt 기준)

  • CalculatorForInt/addCal.py
def add(n1, n2):
    return int(n1 + n2)

if __name__ == '__main__':
    print(add(3.14, 1.2))

 

  • CalculatorForInt/subCal.py
def sub(n1, n2):
    return int(n1 - n2)

if __name__ == '__main__':
    print(sub(3.14, 1.2))

 

  • CalculatorForInt/mulCal.py
def mul(n1, n2):
    return int(n1 * n2)

if __name__ == '__main__':
    print(mul(3.14, 1.2))

 

  • CalculatorForInt/divCal.py
def div(n1, n2):
    return int(n1 / n2)

if __name__ == '__main__':
    print(div(3.14, 1.2))

 

 

▶ 각 모듈 코드(CalculatorForFloat 기준)

CalculatorForInt 모듈 코드와 구조는 같으나 int → float으로 변경해야 함

 

 

▶ 메인 파일: package.py

from CalculatorForInt import addCal
from CalculatorForInt import subCal
from CalculatorForInt import mulCal
from CalculatorForInt import divCal

returnValue = addCal.add(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = subCal.sub(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = mulCal.mul(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = divCal.div(3.14, 0.05)
print(f'returnValue: {returnValue}')




from CalculatorForFloat import addCal
from CalculatorForFloat import subCal
from CalculatorForFloat import mulCal
from CalculatorForFloat import divCal

returnValue = addCal.add(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = subCal.sub(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = mulCal.mul(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = divCal.div(3.14, 0.05)
print(f'returnValue: {returnValue}')




# from CalculatorForInt import addCal as ciAdd
# from CalculatorForInt import subCal as ciSub
# from CalculatorForInt import mulCal as ciMul
# from CalculatorForInt import divCal as ciDiv
from CalculatorForInt import addCal as ciAdd, subCal as ciSub, mulCal as ciMul, divCal as ciDiv

# from CalculatorForFloat import addCal
# from CalculatorForFloat import subCal
# from CalculatorForFloat import mulCal
# from CalculatorForFloat import divCal

from CalculatorForFloat import addCal, subCal, mulCal, divCal

returnValue = ciAdd.add(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = ciSub.sub(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = ciMul.mul(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = ciDiv.div(3.14, 0.05)
print(f'returnValue: {returnValue}')


returnValue = addCal.add(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = subCal.sub(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = mulCal.mul(3.14, 0.05)
print(f'returnValue: {returnValue}')

returnValue = divCal.div(3.14, 0.05)
print(f'returnValue: {returnValue}')

★ 설명 ★

코드 길이가 좀 있는데, 순서에 따라 설명함

  1. import 방식 (정수 계산기 사용)
    • CalculatorForInt 패키지에서 각 연산 모듈을 불러옴
    • 각각의 .add(), .sub() 같은 함수를 호출
    • 각 모듈은 int()로 강제 변환되기 때문에 결과는 정수로 출력
  2. import 방식 (실수용 계산기 사용)
    • 정수용과 같은 방식
    • CalculatorForFloat 패키지에서 모듈들을 불러옴
    • 각 함수들은 float()을 반환 → 소수점까지 계산 결과가 나옴
  3. 별칭 사용 (as) + 혼합 사용
    • CalculatorForInt 모듈들은 별칭(ciAdd 등)을 붙여서 헷갈리지 않게 함
    • CalculatorForFloat은 기본 이름 그대로 유지함

 

  • 주의해야 할 점!
    • addCal 같은 이름이 중복될 경우 가장 마지막 import가 적용됨
    • 그래서 as 키워드를 사용해서 별칭 붙이는 게 이름 충돌 방지에 좋음

 

 

 

[site-packages]

  • site-packages란?
    • site-packages는 Python에서 외부 모듈과 패키지를 저장하는 폴더
    • 이 폴더에 설치된 모듈들은 어디서든 import 해서 사용할 수 있음
    • 우리가 import 해서 쓰는 외부 라이브러리들이 모여 있는 책꽂이 같은 거
  • 왜 필요할까?
    • 우리는 어떤 기능을 자주 쓰기 위해 .py 파일(=모듈)을 만든다.
    • 그런 파일을 여러 프로젝트에서 계속 쓰고 싶으면 어떻게?
      • 매번 복붙 하면 번거로움
      • 그래서 파이썬은 site-packages에 넣어두면 언제 어디서든 쓸 수 있도록 해줌!

 

 

  • site-packages의 위치 확인
import sys

for path in sys.path:
    print(path)

출력 결과 중에 이러한 경로가 있다면, 이 경로가 현재 프로젝트의 site-packages 경로임

C:\Users\홍길동\AppData\Local\Programs\Python\Python39\Lib\site-packages

 

폴더 구조

 

  • calculator/cal.py
# 단순한 사칙연산을 함수로 정의해둔 모듈
def add(n1, n2): return n1 + n2
def sub(n1, n2): return n1 - n2
def mul(n1, n2): return n1 * n2
def div(n1, n2): return n1 / n2

 

  • divisor_pac/divisor_mod.py
def divisor(inputNumber):	# 약수를 리스트로 리턴
    result = []
    for number in range(1, inputNumber + 1):
        if inputNumber % number == 0:
            result.append(number)
    return result

def prime_number(inputNumber):	# 주어진 수까지의 소수 리스트 반환
    result = []
    for number in range(2, inputNumber + 1):
        flag = True
        for n in range(2, number):
            if number % n == 0:
                flag = False
                break
        if flag:
            result.append(number)
    return result

 

  • 실행 파일 : sitePackages.py
import sys
for path in sys.path:
    print(path)

★ 설명 ★

이걸 먼저 실행하면 파이썬이 모듈을 찾는 모든 경로가 출력된다.

그중 하나가 site-packages 경로이고, 여기에 내 모듈이 있다면 어디서든 import 가능하다는 의미

 

▶ 실습 코드 : site-packages에 약수와 소수를 리스트로 반환하는 모듈을 만들어보자

from divisor_pac import divisor_mod as dm

print(f'10의 약수: {dm.divisor(10)}')
print(f'50까지의 소수: {dm.prime_number(50)}')

이건 sitePackages.py (실행 파일)이다.

어떻게 작동하는지 설명하자면

  1. sitePackages.py 파일이 실행
  2. from divisor_pac import divisor_mod as dm으로 site-packages에 있는 모듈을 가져옴
  3. 그 안의 함수들을 직접 정의한 것처럼 자유롭게 사용할 수 있음

 

●코드 실행 결과 

10의 약수: [1, 2, 5, 10]
50까지의 소수: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

 

 

 

 

[자주 사용하는 외부 모듈]

  • 파이썬 기본 내장 함수(수학 관련)

 

 

  • math 모듈
    • import math으로 모듈을 불러와 사용

 

 

  • random 모듈
    • 난수를 생성하거나 랜덤 동작이 필요할 때 사용
    • import random으로 모듈을 불러와 사용

 

 

  • time 모듈
    • 현재 시간 정보를 가져오거나 시간 관련 처리를 할 때 사용
    • import time
      • lt = time.localtime() # 시간을 먼저 받아옴
    • 위 코드를 기본값으로 작성한 뒤 아래 코드를 사용
    • 시간을 먼저 받아와야 세부 정보를 꺼낼 수 있음

  • 이해를 위한 예시 코드
import time

lt = time.localtime()

print(f"지금은 {lt.tm_year}년 {lt.tm_mon}월 {lt.tm_mday}일입니다.")
print(f"현재 시간은 {lt.tm_hour}시 {lt.tm_min}분 {lt.tm_sec}초입니다.")

 

 

 

 

 

[나의 생각 정리]

  • 모듈과 패키지... 정리할 게 정말 많았다.
  • 이해가 되지 않는 부분은 GPT를 이용해서 설명을 듣고 이해했다.
  • 능숙하게 프로젝트에서 사용하려면 여러 코드들을 직접 작성하며 경험치를 쌓아야 할 것 같다.

 

[적용점]

  • 프로젝트를 진행하거나 협업할 때 많이 사용할 것으로 예상된다.

 

 

 

“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”