🐍 νŒŒμ΄μ¬μ—μ„œ __repr__κ³Ό eval(repr(obj)) 관계 μ™„λ²½ μ΄ν•΄ν•˜κΈ°

SueΒ·2025λ…„ 8μ›” 5일
0

Effective Python

λͺ©λ‘ 보기
4/9
post-thumbnail

🐍 νŒŒμ΄μ¬μ—μ„œ __repr__κ³Ό eval(repr(obj)) 관계 μ™„λ²½ μ΄ν•΄ν•˜κΈ°

νŒŒμ΄μ¬μ„ κ³΅λΆ€ν•˜λ‹€ 보면 __repr__ κ³Ό eval(repr(obj)) λΌλŠ” ν‘œν˜„μ„ 자주 보게 λ©λ‹ˆλ‹€.
특히 Effective Python μ•„μ΄ν…œ 75μ—μ„œλŠ” 이 두 κ°œλ…μ˜ 관계λ₯Ό κ°•μ‘°ν•©λ‹ˆλ‹€.
이 κΈ€μ—μ„œλŠ” __repr__의 μ—­ν• , eval(repr(obj))의 의미, 그리고 두 κ°œλ…μ˜ 관계λ₯Ό μƒμ„Ένžˆ μ„€λͺ…ν•©λ‹ˆλ‹€.


βœ… 1. __repr__λž€ 무엇인가?

πŸ“Œ κ°œλ…

  • __repr__은 객체의 β€œκ³΅μ‹μ μΈβ€ λ¬Έμžμ—΄ ν‘œν˜„μ„ λ°˜ν™˜ν•˜λŠ” 특수 λ©”μ„œλ“œμž…λ‹ˆλ‹€.
  • λͺ©μ : 개발자(디버깅) λ₯Ό μœ„ν•œ 객체의 정보 제곡.
  • repr(obj) λ˜λŠ” print(repr(obj))λ₯Ό ν˜ΈμΆœν•˜λ©΄ obj.__repr__() 이 μ‹€ν–‰λ©λ‹ˆλ‹€.

🧩 예제

class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age

user = User("Suyeon", 27)
print(repr(user))  # <__main__.User object at 0x7f...>
  • __repr__을 μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄ κΈ°λ³Έ 좜λ ₯은 λ©”λͺ¨λ¦¬ μ£Όμ†Œλ§Œ λ³΄μ—¬μ€λ‹ˆλ‹€.

βœ… __repr__을 μž¬μ •μ˜ν•˜λ©΄?

class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __repr__(self):
        return f"User({self.name!r}, {self.age!r})"

user = User("Suyeon", 27)
print(repr(user))  # User('Suyeon', 27)
  • 이제 디버깅 μ‹œ 더 μœ μš©ν•œ 정보λ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

βœ… 2. eval(repr(obj))λž€ 무엇인가?

πŸ“Œ κ°œλ…

  • eval() 은 λ¬Έμžμ—΄μ„ 파이썬 μ½”λ“œλ‘œ μ‹€ν–‰ν•˜κ³  κ·Έ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • repr(obj) 의 κ²°κ³Όκ°€ μœ νš¨ν•œ 파이썬 ν‘œν˜„μ‹μ΄λ©΄,
    eval(repr(obj))을 톡해 원본 객체λ₯Ό μž¬μƒμ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

🧩 예제

a = "hello"
b = eval(repr(a))
print(b)         # hello
assert a == b    # βœ… True
  • repr(a) β†’ 'hello'
  • eval("'hello'") β†’ λ¬Έμžμ—΄ "hello" 생성

βœ… 3. __repr__κ³Ό eval(repr(obj))의 관계

πŸ“Œ 관계 μ„€λͺ…

  • 이상적인 __repr__ 은 eval(repr(obj)) == obj λ₯Ό λ§Œμ‘±ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • 즉, repr(obj)의 κ²°κ³Όκ°€ 객체λ₯Ό λ‹€μ‹œ λ§Œλ“€ 수 μžˆλŠ” 파이썬 μ½”λ“œλΌλ©΄ μ΄μƒμ μž…λ‹ˆλ‹€.

🧩 예제: 이상적인 repr****

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

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

p1 = Point(2, 3)
p2 = eval(repr(p1))
print(p2)            # Point(2, 3)
print(p1.x, p1.y)    # 2 3
print(p1.__dict__)   # {'x': 2, 'y': 3}
  • eval(repr(p1)) β†’ μƒˆλ‘œμš΄ Point 객체 생성
  • repr이 디버깅과 객체 μž¬μƒμ„±μ— λͺ¨λ‘ μœ μš©ν•΄μ§.

βœ… 4. repr vs str 차이

ν•­λͺ©__repr____str__
λͺ©μ κ°œλ°œμž λ””λ²„κΉ…μš©μ‚¬μš©μž μΉœν™”μ  좜λ ₯
호좜 방식repr(obj)str(obj)
ꢌμž₯ κ΅¬ν˜„eval(repr(obj)) == obj λ§Œμ‘±ν•˜λ„λ‘μ½κΈ° 쒋은 λ¬Έμžμ—΄

βœ… 5. μ‹€μ „μ—μ„œμ˜ ν™œμš©

  • λ””λ²„κΉ…μš©: __repr__ 을 잘 κ΅¬ν˜„ν•˜λ©΄ print만으둜 λ‚΄λΆ€ μƒνƒœ 확인 κ°€λŠ₯
  • 객체 λ³΅μ›μš©: repr이 evalκ³Ό ν˜Έν™˜λ˜λ©΄ ν…ŒμŠ€νŠΈ 및 직렬화에 유용
  • μ˜ˆμ™Έ 상황: λͺ¨λ“  객체가 eval(repr(obj))을 λ§Œμ‘±ν•  ν•„μš”λŠ” μ—†μŒ (예: 파일 ν•Έλ“€, μ†ŒμΌ“ λ“± 볡원 λΆˆκ°€ 객체)

βœ… 6. eval의 μœ„ν—˜μ„± 주의

  • eval은 μž„μ˜ μ½”λ“œ μ‹€ν–‰ κ°€λŠ₯ β†’ λ³΄μ•ˆμƒ 맀우 μœ„ν—˜.
  • μ‹ λ’°ν•  수 μ—†λŠ” μž…λ ₯μ—λŠ” μ ˆλŒ€ μ‚¬μš©ν•˜μ§€ 말 것.
  • μ•ˆμ „ν•˜κ²Œ 평가할 λ•ŒλŠ” ast.literal_eval을 μ‚¬μš©.

🎯 정리

  • βœ… __repr__: 객체의 곡식적 ν‘œν˜„(디버깅/볡원 λͺ©μ )
  • βœ… eval(repr(obj)): repr(obj)κ°€ 파이썬 μ½”λ“œλΌλ©΄ 원본 객체 μž¬μƒμ„± κ°€λŠ₯
  • βœ… 이상적인 __repr__: eval(repr(obj)) == obj 만쑱
profile
AI/ML Engineer

0개의 λŒ“κΈ€