logging보다 직관적인 디버깅? repr로 해결!

Sue·2025년 8월 5일
0

Effective Python

목록 보기
3/9
post-thumbnail

아래는 「파이썬 코딩의 기술 (Effective Python)」 2판의 아이템 75 "디버깅 출력에는 repr 문자열을 사용하라" 내용을 초보자도 쉽게 이해할 수 있도록 개념 → 코드 분석 → logging과의 차이 → 정리 순으로 꼼꼼하게 설명한 정리입니다.


1. 아이템 75 핵심 아이디어

  • 디버깅 시 print() 대신 repr()을 활용하면 유용하다.

  • 이유:

    • repr()객체를 개발자 친화적으로 표현
    • str()보다 더 많은 정보를 제공
    • eval(repr(obj))로 원본 객체를 복원할 수 있도록 설계되는 경우가 많다
  • 또한, 클래스에 __repr__을 구현하면, 객체의 디버깅 출력이 훨씬 가독성 있게 바뀐다.


2. str vs repr 차이

함수목적출력 특징
str(obj)사용자 친화적, 읽기 쉽게사람이 보기 좋은 문자열
repr(obj)개발자 친화적, 디버깅용객체를 다시 만들 수 있는 표현을 목표
print(obj)내부적으로 str(obj) 호출기본은 사용자 친화적 출력

🧩 3. 코드 예제 분석 (제공 코드 기반)

🔹 기본 print() 사용

print('foo 뭐시기')
  • 단순 출력, 사람이 보기 좋게 문자열 그대로 표시.

🔹 str()와 다양한 출력 방식 비교

my_value = 'foo 뭐시기'
print(str(my_value))          # foo 뭐시기
print('%s' % my_value)        # foo 뭐시기
print(f'{my_value}')          # foo 뭐시기
print(format(my_value))       # foo 뭐시기
print(my_value.__str__())     # foo 뭐시기
  • 모두 사람이 읽기 좋게 문자열을 그대로 출력.
  • 따라서 디버깅 시에는 부족하다 (특수 문자, 공백, 이스케이프 정보가 숨겨짐).

🔹 repr() 사용

a = '\x07'
print(repr(a))   # '\x07'
  • repr()은 이스케이프 문자까지 그대로 보여줌 → 디버깅에 유리.

🔹 repr() → eval() 복원 가능

b = eval(repr(a))
assert a == b
  • repr() 결과를 eval() 하면 원본 객체 복원 가능(가능하도록 설계된 경우).

🔹 숫자와 문자열 비교 시 repr

int_value = 5
str_value = '5'
print(f'{int_value!r} != {str_value!r}')  # 5 != '5'
  • !r 사용 → f-string에서도 repr 출력 강제.

🔹 클래스에서 repr이 없는 경우

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

obj = OpaqueClass(1, 'foo')
print(obj)  
# <__main__.OpaqueClass object at 0x7f3e2c9d5d60>
  • 기본 출력은 메모리 주소만 보여줌 → 디버깅 시 유용하지 않음.

🔹 클래스에서 repr 구현

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

    def __repr__(self):
        return f'BetterClass({self.x!r}, {self.y!r})'

obj = BetterClass(2, '뭐시기')
print(obj)  
# BetterClass(2, '뭐시기')
  • __repr__을 정의하면 디버깅 출력이 더 명확해짐.
  • 속성 값도 명시적으로 확인 가능.

🔹 객체 내부 확인 (dict)

obj = OpaqueClass(4, 'baz')
print(obj.__dict__)  
# {'x': 4, 'y': 'baz'}
  • __dict__로 내부 상태 확인 가능하지만, 매번 수동으로 보기 불편.
  • 따라서 __repr__을 잘 구현하면 훨씬 편리.

4. logging보다 repr이 나은 이유?

많은 초보자가 "디버깅에는 logging을 쓰면 되지 않나?" 라고 생각합니다.
하지만 아이템 75에서 강조하는 부분은 ‘디버깅 출력의 형식’입니다.

🔹 logging과 repr 비교

구분loggingrepr
목적로그 기록 (파일, 콘솔 등)객체를 개발자 친화적으로 출력
출력 포맷사용자가 지정한 메시지 형식객체의 상태를 자동으로 자세히 표시
사용 난이도logging 설정 필요 (레벨, 핸들러 등)print(repr(obj)) 즉시 사용 가능
디버깅 정보기본적으로 str() 사용 → 상세 정보 부족이스케이프, 타입, 내부 표현까지 표시

왜 repr이 더 낫나?

  • 간단한 디버깅에서는 logging보다 repr 출력이 즉시 도움이 됨
  • repr은 객체 내부 상태를 더 많이 보여줌
  • 클래스에서 __repr__ 구현 시 디버깅 출력이 logging보다 직관적

📝 결론: logging은 장기 로그 관리용, repr은 디버깅 순간에 강력.


5. 정리

  1. 디버깅할 때는 print(obj) 대신 print(repr(obj)) 사용
  2. f-string에서는 {obj!r} 사용 → repr 출력 강제
  3. 클래스에 __repr__을 구현하면 print만으로도 강력한 디버깅 가능
  4. logging은 장기 추적용, repr은 즉시 확인용
  5. 특수 문자, 공백, 타입 구분이 필요한 경우 repr 필수

🎯 아이템 75 한 줄 요약

"디버깅할 때는 str이 아닌 repr을 사용하라.
객체의 내부 상태를 더 잘 파악할 수 있고, 클래스에 __repr__을 구현하면 print만으로도 훌륭한 디버깅이 된다."

profile
AI/ML Engineer

0개의 댓글