본문 바로가기
코드/python

파이썬 모듈 관련

by WeZZ 2012. 1. 8.

2) 모듈

모듈이란 함수나 변수들, 또는 클래스들을 모아놓은 파일이다. 다른 파이썬 프로그램에서 불러쓸 수 있게끔 만들어진 파이썬 파일을 모듈이라 부른다.

우리는 파이썬으로 프로그래밍을 할 때 굉장히 많은 모듈을 사용한다. 물론 이미 다른 사람들에 의해서 만들어진 파이썬 라이브러리들이 그 대표적인 것이 되겠지만 우리가 직접 만들어서 사용해야 할 경우도 생길 것이다. 여기서는 모듈을 어떻게 만들고 또 사용할 수 있는지에 대해서 자세하게 알아보기로 하자.


모듈 만들고 불러보기

우선 모듈에 대해서 자세히 살펴보기 전에 간단한 모듈을 한번 만들어 보기로 하자.

# mod1.py
def sum(a, b):
    return a + b

위와 같이 sum 함수만을 가지고 있는 파일 mod1py를 만들고 저장하여 보자. 그리고 MS도스창을 열고 mod1.py를 저장한 곳으로 이동한 다음에 대화형 인터프리터를 실행시키고 아래와 같이 따라해 보자. 꼭 mod1.py가 저장한 위치로 이동한 다음 다음을 실행해야 한다. 그래야만 대화형 인터프리터에서 mod1.py를 읽을 수 있다. import 는 현재 디렉토리에 있는 파일이나 파이썬 라이브러리가 저장되어진 디렉토리에 있는 파이썬 모듈만을 불러올 수 있다. 이 사항에 대해서는 잠시 후에 알아보도록 하자.


우리가 만든 mod1.py라는 파일을 파이썬에서 불러서 쓰려면 어떻게 할까? 다음은 import의 사용법이다.

import 모듈이름


여기서 모듈이름은 mod1.py에서 ".py"라는 확장자를 제거한 mod1만을 가리키는 것이다.

>>> import mod1 
>>> print mod1.sum(3,4) 
7

위처럼 mod1.py를 불러오기 위해서 import mod1과 같이 하였다. import mod1.py과 같이 사용하는 실수를 하지 않도록 주의 하자. import는 이미 만들어진 파이썬 모듈을 사용할 수 있게 해주는 것이다. mod1.py파일에 있는 sum함수를 이용하기 위해서는 위의 예에서와 같이 mod1.sum처럼 모듈이름 뒤에 '.'(도트 연산자)를 붙이고 함수이름을 써서 사용할 수 있다.


이번에는 mod1.py에 다음의 함수를 추가 시켜 보자.

def safe_sum(a, b): 
    if type(a) != type(b): 
        print "더할수 있는 것이 아닙니다." 
        return 
    else: 
        result = sum(a, b) 
    return result

위의 함수가 하는 역할은 서로 다른 타입의 객체끼리 더하는 것을 방지해 준다. 만약 서로 다른 형태의 객체가 입력으로 들어오면 “더할 수 있는 값이 아닙니다”라는 메시지를 출력하고 return문만 단독으로 사용되어 None값을 돌려주게 된다.


이 함수를 mod1.py에 추가 시킨다음 다시 대화형 인터프리터를 열고 다음과 같이 따라하자.

>>> import mod1 
>>> print mod1.safe_sum(3, 4) 
7


import mod1으로 mod1.py파일을 불러온다. 다음에 mod1.safe_sum(3, 4)로 safe_num함수를 호출한다.

>>> print mod1.safe_sum(1, 'a') 
더할  있는 값이 아닙니다. 
None 
>>>

만약 서로 다른 형태의 객체가 입력으로 들어오면 에러 메시지를 출력하고 단독으로 쓰인 return에 의해서 None이라는 것을 돌려주게 된다.


또한 sum함수도 다음처럼 바로 호출할 수 있다.

>>> print mod1.sum(10, 20) 
30


때로는 mod1.sum, mod1.safe_sum 처럼 쓰기 보다는 그냥 sum, safe_sum 처럼 함수를 쓰고 싶은 사람도 있을 것이다. 이럴때는 “from 모듈이름 import 모듈함수”를 사용하면 된다.

from 모듈이름 import 모듈함수


다음과 같이 따라해 보자.

>>> from mod1 import sum 
>>> sum(3, 4) 
7

from ~ import ~를 이용하면 위에서 처럼 모듈이름을 붙이지 않고 바로 해당 모듈의 함수를 쓸 수 있다. 하지만 위와 같이 하면 mod1.py파일의 sum함수만을 사용할 수 있게 된다. 그렇다면 sum함수와 safe_sum함수를 둘다 사용하고 싶을 땐 어떻게 해야 할까?


두가지 방법이 있다.

from mod1 import sum, safe_sum

첫 번째 방법은 위에서 보는 것과 같이 from 모듈이름 import 모듈함수1, 모듈함수2 처럼 사용하는 방법이다. 콤마로 구분하여 필요한 함수를 불러올 수 있는 방법이다.

from mod1 import *

두 번째 방법은 위와같이 * 문자를 이용하는 방법이다. '*'가 모든 것을 뜻한다고 대부분 알고 있는데 파이썬에서도 마찬가지이다. 위의 from mod1 import *가 뜻하는 말은 mod1.py의 모든 함수를 불러서 쓰겠다는 말이다. mod1.py에는 함수가 2개 밖에 존재하지 않기 때문에 위의 두가지 방법은 동일하게 적용될 것이다.


if __name__ == "__main__": 의 의미

이번에는 mod1.py 파일에 다음과 같이 추가하여 보자.

# mod1.py 
def sum(a, b): 
    return a+b 

def safe_sum(a, b): 
    if type(a) != type(b): 
        print "더할수 있는 것이 아닙니다." 
        return 
    else: 
        result = sum(a, b) 
    return result 


print safe_sum('a', 1) 
print safe_sum(1, 4) 
print sum(10, 10.4)

위와 같은 mod1.py를 에디터로 작성해서 C:\Python이란 디렉토리에 저장을 했다면 위의 프로그램 파일을 다음처럼 실행할 수 있다.

C:\Python> python mod1.py
더할수 있는 것이 아닙니다.
None
5
20.4

결과값은 위처럼 나올 것이다. 하지만 문제는 이 mod1.py라는 파일을 import해서 쓰려고 할 때 생긴다.


도스창을 열고 다음을 따라해 보자.

C:\WINDOWS> cd \Python
C:\Python> python
Python 2.1 (#15, Apr 16 2001, 18:25:49) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>> import mod1
더할수 있는 것이 아닙니다.
None
5
20.4

위와 같은 결과를 볼 수 있을 것이다. 우리는 단지 mod1.py파일의 sum과 safe_sum함수만을 쓰려고 했는데 위처럼 import mod1을 하는 순간 mod1.py가 실행이 되어서 결과값을 출력한다. 이러한 것을 방지하기 위한 것이 있다.


mod1.py파일에서 마지막 부분을 다음과 같이 수정해 보자.

if __name__ == "__main__": 
    print safe_sum('a', 1) 
    print safe_sum(1, 4) 
    print sum(10, 10.4)

이것이 뜻하는 의미는 C:\Python> python mod1.py 처럼 직접 이 파일을 실행시켰을 때는 __name__ == "__main__" 이 참이 되어 if문 다음 문장들이 수행되고 대화형 인터프리터나 다른 파일에서 이 모듈을 불러서 쓸때는 __name__ == "__main__"이 거짓이 되어 if문 아래문장들이 수행되지 않도록 한다는 뜻이다.


파이썬 모듈을 만든 다음 보통 그 모듈을 테스트하기 위해서 위와 같은 방법을 쓴다. 실제로 그런지 대화형 인터프리터를 열고 실행해 보자.

>>> import mod1 
>>>

위와 같이 고친 다음에는 아무런 결과값을 출력하지 않는 것을 볼 수 있다.


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

위에서 알아본 모듈은 함수만을 포함하고 있지만 클래스나 변수등을 포함할 수도 있다. 다음의 프로그램을 작성해 보자.

# mod2.py 
PI = 3.141592 

class Math: 
    def solv(self, r): 
        return PI * (r ** 2) 


def sum(a, b): 
    return a+b 

if __name__ == "__main__": 
    print PI 
    a = Math() 
    print a.solv(2) 
    print sum(PI , 4.4)

클래스와 함수, 변수등을 모두 포함하고 있는 파일이다. 이름을 mod2.py로 하고 C:\Python이란 디렉토리에 저장했다고 가정을 해 보자.


다음과 같이 실행할 수 있다.

C:\Python> python mod2.py
3.141592
12.566368
7.541592


이번에는 대화형 인터프리터를 열고 다음과 같이 따라해 보자.

C:\Python> python
Python 2.1 (#15, Apr 16 2001, 18:25:49) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>> import mod2
>>>

__name__ == "__main__"이 거짓이 되므로 아무런 값도 출력되지 않는다.

>>> print mod2.PI 
3.141592

mod2.PI 처럼 mod2.py에 있는 PI라는 변수값을 사용할 수 있다.

>>> a = mod2.Math() 
>>> print a.solv(2) 
12.566368

위의 예는 mod2.py에 있는 클래스 Math를 쓰는 방법을 보여준다. 위에서 보듯이 모듈내에 있는 클래스를 이용하기 위해서는 '.'(도트연산자)를 이용하여 클래스이름 앞에 모듈이름을 먼저 써 주어야 한다.

>>> print mod2.sum(mod2.PI, 4.4) 
7.541592

mod2.py에 있는 함수 sum역시 당연히 사용할 수 있다.


다른 프로그램 파일에서 만든 모듈 불러오기

만들어놓은 모듈 파일을 써 먹기 위해서 지금까지 대화형 인터프리터 만을 이용했는데 이번에는 새롭게 만들 파이썬 파일 내에서 이전에 만들어 놓았던 모듈을 불러서 쓰는 방법에 대해서 알아보기로 하자. 바로 이전에 만든 모듈인 mod2.py라는 파일을 새롭게 만들 파이썬 프로그램 파일에서 불러보도록 하자. 자! 그럼 에디터로 다음을 함께 작성해 보자.

# modtest.py 
import mod2 

result = mod2.sum(3, 4) 
print result

위에서 보듯이 파일에서도 대화형 인터프리터에서 한 것과 마찬가지 방법으로 import mod2로 mod2 모듈을 불러와서 쓰면 된다. 여기서 중요한 것은 modtest.py라는 파일과 mod2.py라는 파일이 동일한 디렉토리에 있어야만 한다는 점이다.


모듈 불러오는 또다른 방법

우리는 지금껏 만든 모듈을 써먹기 위해서 도스창을 열고 모듈이 있는 디렉토리로 이동한 다음에나 쓸 수 있었다. 하지만 항상 이렇게 해야 하는 불편함을 해소할 수 있는 방법이 있다.

만약 독자가 만든 파이썬 모듈을 항상 C:\Python\Mymodules 라는 디렉토리에 저장했다면 그 디렉토리로 이동할 필요없이 모듈을 불러서 쓸 수 있는 방법에 대해서 알아보자.

우선 위에서 만든 mod2.py모듈을 C:\Python\Mymodules라는 디렉토리에 저장한 다음에 다음의 예를 따라해 보도록 하자.


먼저 sys 모듈을 불러보자.

>>> import sys

sys 모듈은 파이썬을 설치할 때 함께 오는 라이브러리 모듈이다. sys에 대한 얘기는 3장에서 또다시 다룰 것이다. 우리는 sys모듈을 이용해서 파이썬 라이브러리가 설치되어 있는 디렉토리를 확인 할 수 있다.


다음과 같이 해보자.

>>> sys.path 
>>> sys.path 
['', 'c:\\', 'c:\\python21\\dlls', 'c:\\python21\\lib', 'c:\\python21\\lib\\plat-win', 
'c:\\python21\\lib\\lib-tk', 'c:\\python21']

sys.path는 파이썬 라이브러리들이 설치되어 있는 디렉토리들을 보여준다. 또한 파이썬 모듈이 위의 디렉토리에 들어있는 경우에는 해당 디렉토리로 이동할 필요 없이 바로 불러서 쓸 수가 있다. 그렇다면 sys.path에 C:\Python\Mymodues라는 디렉토리를 추가하면 아무데서나 불러쓸 수 있을까?


당연하다.


sys.path의 결과값이 리스트 였으므로 우리는 다음과 같이 할 수 있을 것이다.

>>> sys.path.append("C:\Python\Mymodules") 
>>> sys.path 
['', 'c:\\', 'c:\\python21\\dlls', 'c:\\python21\\lib', 'c:\\python21\\lib\\plat 
-win', 'c:\\python21\\lib\\lib-tk', 'c:\\python21', 'C:\\Python\\Mymodules'] 
>>>

sys.path.append를 이용해서 C:\Python\Mymodules라는 디렉토리를 sys.path에 추가시키고 다시 sys.path를 보았더니 가장 마지막 요소에 C:\\Python\\Mymodules라고 추가 된 것을 확인 할 수 있었다.


그렇다면 실제로 모듈을 불러서 쓸 수 있는지 확인해보자.

>>> import mod2 
>>> print mod2.sum(3,4) 
7

이상 없이 불러서 쓸 수 있다. 이렇게 특정한 디렉토리에 있는 모듈을 불러서 쓰고 싶을 때 사용하는 것이 바로 sys.path.append(모듈디렉토리)의 방법이다.


reload

reload는 이미 불렀던(import한) 모듈에 변경 사항이 생겼을 때 다시 그 모듈을 불러서 새로운 사항을 적용시키는 것이다. 아마도 파이썬 초보자는 이 기능을 별로 사용할 일이 없을 것이다. 하지만 모듈을 바꾸어가며 대화형 인터프리터에서 테스트할 때 reload는 매우 유용하게 쓰일 것이다. 다음과 같이 대화형 인터프리터에서 따라해 보자.

>>> import mod2 
>>> print mod2.PI 
3.141592


대화형 인터프리터를 아직 닫지 말고 에디터로 mod2.py의 PI 부분을 다음 처럼 수정하자.

PI = 3.14


PI를 좀더 간단한 값(3.14)으로 바꾸었다. 다음에 대화형 인터프리터 모드로 돌아가서 다음과 같이 해보자.

>>> reload(mod2) 
>>> print mod2.PI 
3.14

바뀐 변수값으로 출력되었음을 확인할 수 있다. reload대신에 import를 다시 하여도 바뀐값이 적용되지 않을까? 라는 의심이 드는 독자들은 직접 한번 실행 해 보기를 바란다. reload를 하면 바뀐 값이 적용되지만 import는 이전의 값을 유지하고 있음을 알게 될 것이다. 하지만 위에서 mod2.py파일을 수정한 다음 대화형 인터프리터를 닫고 다시 대화형 인터프리터를 실행한 후 import mod2를 하면 변경된 사항이 적용되는 것은 당연한 일이다.