Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python pyclbr 모듈 활용법: 클래스 브라우저 지원

pyclbr 모듈이란?

파이썬 표준 라이브러리의 pyclbr(Python Class Browser) 모듈은 파이썬 모듈 내에 정의된 함수, 클래스, 메서드에 대한 정보를 추출하는 기능을 제공합니다. 이 모듈의 가장 큰 특징은 대상 모듈을 실제로 임포트(import)하지 않고 소스 코드만 분석한다는 점입니다. 따라서 모듈 실행 시 발생할 수 있는 부작용(side effect) 없이도 안전하게 모듈의 구조를 파악할 수 있습니다.

readmodule() 함수

pyclbr 모듈은 readmodule() 함수를 제공합니다. 이 함수는 모듈 이름을 인자로 받아, 해당 모듈의 최상위(모듈 레벨) 클래스 이름을 키로 하고 클래스 디스크립터(descriptor)를 값으로 하는 딕셔너리를 반환합니다.

인자로 전달되는 모듈 이름은 패키지 내부에 있는 모듈일 수도 있습니다. 이 경우 path 인자에 디렉터리 경로들의 시퀀스를 지정하면, 해당 경로들이 sys.path 앞에 추가되어 모듈 소스 코드를 찾는 데 사용됩니다.

다음 예제는 readmodule() 함수를 사용해 파이썬 표준 라이브러리의 socket 모듈에 정의된 클래스와 메서드를 분석합니다.

import pyclbr

mod = pyclbr.readmodule("socket")

def show(c):
    s = "class " + c.name
    print(s + ":")
    methods = c.methods.items()
    for method, lineno in methods:
        print("  def " + method)
    print()

for k, v in mod.items():
    show(v)

실행 결과는 다음과 같습니다.

class IntEnum:

class IntFlag:
  def _missing_
  def _create_pseudo_member_
  def __or__
  def __and__
  def __xor__
  def __invert__

class _GiveupOnSendfile:

class socket:
  def __init__
  def __enter__
  def __exit__
  def __repr__
  def dup
  def accept
  def makefile
  def sendfile
  def close
  def detach
  ...

class SocketIO:
  def __init__
  def readinto
  def write
  def readable
  def writable
  def close
  ...

readmodule_ex() 함수

pyclbr 모듈은 readmodule_ex() 함수도 정의하고 있습니다. 이 함수는 모듈 내에 정의된 각 함수와 클래스에 대한 디스크립터를 담은 딕셔너리를 반환하며, 최상위 함수와 클래스 이름이 딕셔너리의 키가 됩니다. 중첩(nested)된 객체들은 부모 객체의 children 딕셔너리에 저장됩니다.

>>> x = pyclbr.readmodule_ex('socket')

>>> for k, v in x.items():
        print(k, v)

IntEnum <pyclbr.Class object at 0x000002095D7D0048>
IntFlag <pyclbr.Class object at 0x000002095D7D04E0>
_intenum_converter <pyclbr.Function object at 0x000002095D82F940>
_GiveupOnSendfile <pyclbr.Class object at 0x000002095D822898>
socket <pyclbr.Class object at 0x000002095D8227B8>
fromfd <pyclbr.Function object at 0x000002095D8340B8>
socketpair <pyclbr.Function object at 0x000002095D834128>
SocketIO <pyclbr.Class object at 0x000002095D82FA20>
create_connection <pyclbr.Function object at 0x000002095D834518>
getaddrinfo <pyclbr.Function object at 0x000002095D834550>

이러한 함수들은 사용자가 직접 작성한 커스텀 모듈에도 그대로 적용할 수 있어, 자신이 정의한 클래스와 메서드 목록을 손쉽게 확인할 수 있다는 장점이 있습니다.

커스텀 모듈 분석 예제

다음 예제에서는 'triangles.py' 모듈의 클래스 구조를 분석해 보겠습니다.

# triangles.py
import math

class Triangle:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def area(self):
        s = (self.a + self.b + self.c) / 2
        area = math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))
        return area

class EquiTriangle(Triangle):
    def __init__(self, a):
        b = a
        c = a
        super().__init__(a, b, c)

    def area(self):
        area = math.sqrt(3) * pow(self.a, 2) / 4
        return area

이제 'triangles' 모듈의 클래스와 메서드 정보를 readmodule_ex()로 가져와 보겠습니다.

>>> br = pyclbr.readmodule_ex('triangles')
>>> for i, j in br.items(): print(i, j.methods)

Triangle {'__init__': 3, 'area': 7}
EquiTriangle {'__init__': 12, 'area': 16}

Class 객체와 Function 객체

pyclbr 모듈은 Function 객체Class 객체, 두 가지 객체를 정의합니다.

Function 객체의 주요 속성

file함수가 정의된 파일의 이름입니다.
module해당 함수를 정의한 모듈의 이름입니다.
name함수의 이름입니다.
lineno정의가 시작되는 파일 내 줄 번호입니다.
parent최상위 함수인 경우 None이며, 중첩 함수인 경우 부모 객체입니다.
children중첩된 함수와 클래스의 이름을 디스크립터에 매핑하는 딕셔너리입니다.

Class 객체의 추가 속성

Class 객체는 위 속성들에 더해 다음 두 가지 속성을 추가로 가집니다.

super해당 클래스의 직계 기반(base) 클래스들을 나타내는 Class 객체들의 리스트입니다.
methods메서드 이름을 줄 번호에 매핑하는 딕셔너리입니다.