본문 바로가기

진리는어디에/Python

[Python] 모듈 객체(module object)

이번 포스트에서는 저번 파이썬 모듈에 이어 "모듈 객체(module object)"에 대해 살펴 본다. 이번 장은 코드 작성을 통해 무엇을 만들어 보기 보다는 모듈 객체를 통해 얻을 수 있는 정보들을 알아 보는 위주로 진행 된다.

모듈 객체란

지금 까지 강의에서 파이썬은 모든 것이 객체로 관리 된다고 이야기 해왔다. 모듈은 하나의 객체이며 어떤 함수와 클래스가 모듈 안에 있고 모듈의 이름은 무엇인지, 어떤 파일인지에 대한 정보들을 가지고 있다.

모듈 역시 객체이므로 아래와 같이 주소와 타입, 사이즈 등을 확인 할 수 있다.

import mylib
import sys

print('address :',hex(id(mylib)))
print('type :', type(mylib))      #<class 'module'>
print('size :', sys.getsizeof(mylib))

주요 속성 소개

모듈 객체 역시 다른 객체들과 마찮가지로 여러가지 어트리뷰트들을 가지고 있다. 그 중 몇 가지만 간략하게 추려서 소개 하도록 하겠다.

아래와 같은 mylib.py 이 실행 파일과 같은 디렉토리에 있다고 가정하고 mylib 모듈의 주요 속성들을 확인해 보도록 하겠다.

'''
    module : mylib.py
    desc : this is test module
'''

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

class Point :
   def __init__(self, x, y) :
       self.x = x
       self.y = y

모듈 객체의 대략적인 모습

  • __doc__ : 모듈을 작성 할 때 모듈의 맨위에 멀티 라인 주석을 추가하면 모듈의 __doc__ 어트리뷰트에 저장 된다.
  • __name__ :  파일 이름에서 확장자를 제외한 부분이 모듈의 이름으로 저장 된다. eg) mylib.py -> mylib
  • __file__ : 경로와 확장자를 포함한 파일 이름이 저장 된다.
import mylib

print(mylib.__doc__)

# OUTPUT :
# module : mylib.py
# desc : this is test module

print(mylib.__name__) # mylib
print(mylib.__file__) # D:\mylib.py

모듈 객체가 가지고 있는 모든 것을 알고 싶다면 간단히 print(dir(mylib))를 이용해 모듈에 속한 모든 변수와 메소드를 확인 할 수 있다.

아니면 아래 처럼 반복문을 이용해 보기 좋게 출력하는 방법도 있다. 아래에 사용되는 getattr은 아래 섹션에서 다시 설명하도록 하겠다. 

import mylib

for s in dir(mylib) :
    at = getattr(mylib, s)          # s. 문자열로 된 모듈 내 속성
    print(f'{s:>13} : {type(at)}')  # 오른쪽으로 13자리를 유지

# <class 'type'>
#         Point : <class 'type'>
#  __builtins__ : <class 'dict'>
#    __cached__ : <class 'str'>
#       __doc__ : <class 'str'>
#      __file__ : <class 'str'>
#    __loader__ : <class '_frozen_importlib_external.SourceFileLoader'>
#      __name__ : <class 'str'>
#   __package__ : <class 'str'>
#      __spec__ : <class '_frozen_importlib.ModuleSpec'>
#           add : <class 'function'>

동적으로 모듈 객체의 속성(타입, 함수 등) 얻기

모듈 역시 객체이기 때문에 getattr() 함수를 이용해 문자열로 모듈의 다양한 속성(타입, 함수 등)을 얻을 수 있다. 

f = getattr(mylib, '함수 또는 클래스 이름')

※ getattr() 함수에 대한 자세한 내용은 [여기]를 참고 한다.

import mylib

f = getattr(mylib, 'add') # 모듈 mylib 에서 add 함수를 얻어 온다

print(type(f))            # <class 'function'>
n = f(1, 2)

print(n)                  # 3

위 예제는 mylib 모듈 객체로 부터 add를 얻어 온다. add는 함수이므로 위 예제에서 f는 함수 객체가 되어 f(1, 2)와 같은 형태로 호출 가능하다.

아래 예제를 이어 살펴 보자. mylib 모듈 객체에 정의 된 클래스를 getattr() 함수를 이용해 얻어 오고 있다.

p = getattr(mylib, 'Point')

print(type(p))            # <class 'type'>

p1 = p(1, 2)

Point 클래스는 타입이므로, getattr() 함수는 타입 객체를 리턴 한다. 우리는 이 타입 객체를 이용해 새로운 Point의 객체를 만들어 낼 수 있다.

builtins 모듈

파이썬에는 모든 표준 타입과 표준 함수를 가지고 있는 builtins 라는 모듈이 있다. 우리가 지금 까지 자주 써왔던 print() 함수도 builtins 모듈에 속한 것이다.

정확하게는 print() 함수를 사용하기 위해서 builtins 모듈을 임포트(import) 후 사용해야 하지만, builtins는 특별한 모듈로써 기본적으로 임포트하지 않아도 사용 가능하다.

  • builtin 모듈은 파이썬 표준 타입과 표준 함수를 가지고 있는 모듈이다.
  • import 하지 않아도 사용 가능하다.
  • __builtins__ 이름으로 접근 하는 것도 가능하다.
import builtins          # 임포트 하지 않아도 상관 없다

print('hello')              # ok
builtins.print('hello')     # ok
__builtins__.print('hello') # ok, __builtins__ 이름으로 접근 할 수 있다.

# builtins의 모든 함수와 클래스 출력
for s in dir(__builtins__) :
    at = getattr(__builtins__, s)
    print(f'{s:>25 : {type(at)}')

모든 모듈들의 정보 얻기

현재 로딩 되어 있는 모든 모듈들의 정보를 얻으려면 sys.modules를 사용한다. sys.modules는 딕셔너리 형태로 되어 있어 아래와 같이 모듈의 이름으로 특정 모듈의 정보를 얻어 오는 것이 가능하다.

import sys

print(sys.modules)

m = sys.modules[__name__] # 현재 모듈의 참조
print(m)
  • 모든 모듈의 정보를 얻으려면 sys.modules를 사용한다. sys.module는 딕셔너리다.
  • 현재 모듈의 잠조를 얻으려면 sys.modules[__name__] 와 같이 __name__ 속성을 이용 할 수 있다.

마치며

이상 파이썬에서 모듈 객체를 통해 알아 낼 수 있는 정보들에는 무엇이 있는지와 getattr() 함수를 이용하여 모듈 객체의 속성들을 동적으로 얻어 올 수 있는 방법을 알아 보았다.

여기 까지 파이썬 모듈에 대한 설명은 마무리 하고 다음 포스트에서는 파이썬에서 예외를 처리하는 방법에 대해 알아 보도록 하겠다.

부록 1. 같이 보면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!