05-2 ~ 05-3 (p.207 ~ p.221)

 

점점 진도가 나갈수록 심화되는 내용이 나오다 보니 확실히 전보다 더 공부하는 시간이 오래 걸린다.

공부 시간이 오래 걸리는 데는 교재에 나와 있지 않은 예들을 실행되는지 테스트해 보느라고 그런 것도 있는 것 같다.

하지만 공부한 것들을 이해하게 되면 지나간 시간이 아깝지 않다. 프로그래밍 공부는 될 때까지 시도해 보는 근성도 중요한 것 같다.

 

아무도 나를 막을 수 없으셈!

 


 

05-2 모듈

 

모듈이란 함수나 변수 또는 클래스를 모아 놓은 파일이다.

다른 파이썬 프로그램에서 불러와 사용할 수 있게끔 만든 파이썬 파일이다.

다른 사람이 이미 만들어 놓은 모듈을 사용할 수도 있고 직접 만들어서 사용할 수도 있다.

# 모듈의 예
# mod1.py
def add(a, b):
    return a + b
    
def suv(a, b):
    return a - b
# .py로 만든 파이썬 파일은 모두 모듈

 

모듈 불러오기

# 명령프롬프트(cmd)
C:\Users\a_jb97> cd C:\doit # mod1.py를 저장한 디렉터리로 이동
C:\doit>dir # C:\doit 디렉터리에 파일이 있는지 확인
...
2022-02-10 오후 09:10 50 mod1.py
...
C:\doit> python # 대화형 인터프리터 실행
>>> import mod1 # import는 이미 만들어 놓은 파이썬 모듈을 사용할 수 있게 해주는 명령어
                # import는 현재 디렉터리에 있는 파일이나 파이썬 라이브러리가 저장된 디렉터리에 있는 모듈만 불러올 수 있음
                # 모듈 이름은 .py를 제거한 mod1만 작성
>>> print(mod1.add(3, 4)) # add 함수를 사용하기 위해서는 모듈 이름 뒤에 '.'(도트 연산자)를 붙이고 함수 이름
7
>>> print(mod1.sub(4, 2))
2

# 모듈 이름 없이 함수 이름만 쓰고 싶을 때
>>> from mod1 import add
>>> add(3, 4)
7

# add, sub 함수 둘 다 사용하고 싶을 때
1. from mod1 import add, sub
2. from mod1 import* # *는 '모든 것'이라는 뜻

 

if __name__ = "__main__": 의 의미

# mod1.py
def add(a, b):
    return a + b
    
def suv(a, b):
    return a - b
    
print(add(1, 4))
print(sub(4, 2))

# cmd
C:\doit> python
>>> import mod1
5
2 # mod1.py 파일의 add와 sub 함수만 사용하려고 했는데 결괏값이 출력


# 이러한 문제 방지
# mod1.py
def add(a, b):
    return a + b
    
def suv(a, b):
    return a - b

if __name__ == "__main__": # 직접 파일을 실행하면 참이 되어 if문 다음 문장 수행
                           # 대화형 인터프리터나 다른 파일에서 이 모듈을 불러서 사용할 때는 거짓이 되어 if문 다음 문장이 수행되지 않음
    print(add(1, 4))
    print(sub(4, 2))
   
import mod1
>>> # 아무것도 수행되지 않음

 

클래스나 변수 등을 포함한 모듈

# mod2.py
PI = 3.141592

class Math:
    def solv(self, r):
        return PI * (r ** 2)
    
def add(a, b):
    return a + b

# cmd
C:\doit>python
>>> import mod2
>>> print(mod2.PI) # mod2.py에 있는 PI 변수 값 사용

>>> a = mod2.Math()
>>> print(a.solv(2)) # mod2.py에 있는 Math 클래스 사용
12.566368

>>> print(mod2.add(mod2.PI, 4.4)) # mod2.py에 있는 add 함수 사용
7.541592

 

다른 파일에서 모듈 불러오기

# modtest.py
import mod2 # mod2.py 파일을 불러옴
            # 현재 모듈과 불러올 모듈이 동일한 디렉터리에 있어야 함
result = p212.add(3, 4)
print(result)

* 모듈을 불러오는 또 다른 방법(모듈을 저장한 디렉터리로 이동하지 않고 모듈을 불러와서 사용)

# cmd
C:\doit>mkdir mymod # 새 디렉터리 생성
C:\doit>move mod2.py mymod # 지정한 디렉터리로 파일 이동
        1개 파일을 이동했습니다.

# 1. sys.path.append(모듈을 저장한 디렉터리) 사용하기
# cmd
C:\doit>python
>>> import sys # sys 모듈 불러옴
>>> sys.path # 파이썬 라이브러리가 설치되어 있는 디렉터리를 보여줌
>>> sys.path.append("C:\doit\mymod")
>>> sys.path
sys.path(파이썬 라이브러리)에 'C:\doit\mymod' 디렉터리 추가
>>> import mod2
>>> print(mod2.add(3, 4))
7

# 2. PYTHONPATH 환경 변수 사용하기
# cmd
C:\doit>set PYTHONPATH=C:\doit\mymod # set 명령어 사용해 PYTHONPATH 환경변수에 mod2.py 파일이 있는 C:\doit\mymod 디렉터리 설정
C:\doit>python
>>> import mod2
>>> print(mod2.add(3, 4))
7

 

05-3 패키지

 

패키지는 도트'.'를 사용하여 파이썬 모듈을 계층적(디렉터리 구조)으로 관리할 수 있게 해준다.

모듈 이름이 A.B인 경우, A는 패키지 이름이 되고 B는 A 패키지의 B 모듈이 된다.

패키지는 디렉터리, 파이썬 모듈로 이루어져 있다.

# 패키지의 구조 (ex.게임)
game/ # 디렉터리
  __init__.py # 모듈
  sound/
    __init__.py
    echo.py
    wav.py
  graphic/
    __init__.py
    screen.py
    render.py
  play/
    __init__.py
    run.py
    test.py

* 패키지 구조로 프로그램을 만들면 공동 작업이나 유지 보수가 용이하다.

 

패키지 만들기

패키지 기본 구성 요소 준비하기

  1. 디렉터리 생성(game, graphic, sound)

디렉터리 생성

  2. 각 디렉터리에 __init__.py 파일 생성

 

  3. 각 디렉터리에 필요한 모듈(.py파일) 생성

 

  4. game 패키지를 참조하도록 명령 프롬프트 창에서 set 명령어로 PYTHONPATH 환경 변수에 C:\doit 디렉터리 추가

 

패키지 안의 함수 실행하기

다음 예제들은 import 예제이므로 하나의 예제를 실행하고 나서 다음 예제를 실행할 때는 인터프리터를 종료하고 다시 실행. (윈도우는 인터프리터 종료 : Ctrl + z)

# cmd
# 1. echo 모듈을 import하여 실행
C:\doit>python
>>> import game.sound.echo
>>> game.sound.echo.echo_test()
echo

# 2. echo 모듈이 있는 디렉터리까지를 from...import 하여 실행
>>> from game.sound import echo
>>> echo.echo_test()
echo

# 3. echo 모듈의 echo_test함수를 직접 import하여 실행
>>> from game.sound.echo import echo_test
>>> echo_test()
echo

# 실행 불가능 예
>>> import game
>>> game.sound.echo.echo_test()
오류 발생 # import game을 수행하면 game 디렉터리의 모듈 또는 game 디렉터리의 __init__.py에 정의한 것만 참조 가능

>>> import game.sound.echo.echo_test
오류 발생 # 도트 연산자'.'를 사용해서 import a.b.c처럼 import할 때 가장 마지막 항목인 c는 반드시 모듈 또는 패키지여야만 함

 

__init__.py 의 용도

__init__.py 파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.

만약 패키지에 포함된 디렉터리에 __init__.py 파일이 없다면 패키지로 인식되지 않는다.

* Python 3.3 버전부터는 __init__.py 파일이 없어도 패키지로 인식하지만 하위 버전 호환을 위해 생성하는 것이 좋다.

# cmd
C:\doit>python
>>> from game.sound import*
>>> echo.echo_test()
오류 발생

# 특정 디렉터리의 모듈을 *를 사용하여 import할때는 다음과 같이 해당 디렉터리의 __init__.py 파일에
  __all__ 변수를 설정하고 import할 수 있는 모듈을 정의해 주어야 한다.

# C:/doit/game/sound/__init__.py
__all__ = ['echo', 'ringtone']

# cmd
C:\doit>python
>>> from game.sound import*
>>> echo.echo_test()
echo

 

relative 패키지

# render.py
from game.sound.echo import echo_test # 추가하여 echo_test 함수를 사용할 수 있게 함
def render_test():
    print("render")
    echo_test()
    
# cmd
C:\doit>python
>>> from game.graphic.render import render_test
>>> render_test()
render
echo


# relative하게 import
# render.py
from ..sound.echo import echo_test # ..은 부모 디렉터리를 뜻함
                                   # graphic과 sound 디렉터리는 동일한 깊이이므로 사용 가능

def render_test():
    print("render")
    echo_test()
# ..같은 relative한 접근자는 모듈 안에서만 사용 가능

 

+ Recent posts