python

python __str__ vs __repr__ 차이점

yscho03 2023. 8. 5. 23:52
728x90
반응형

개요

파이썬 클래스를 사용할때 __str__ 또는 __repr__ 정의하고 사용할 때가 많다. 시간이 없고 바빠서 빼놓고 코딩할 때도 있긴하지만 정의를 해두고 사용하면 디버깅을 하거나 출력할때 유용하게 사용할 수 있다.
이 둘은 비슷해 보이지만 목적과 사용 시점에 따라 약간의 차이점을 가질 수 있다.
 

__str__ vs __repr__

__str__

  • "사람이 읽을 수 있는" 친화적인 형태의 문자열 표현식이다.
  • 사용자가 객체를 문자열로 변환하거나 print() 함수로 출력할 때 호출된다.
  • __str__ 메서드가 정의되지 않은 경우, 파이썬은 대신 __repr__ 메서드를 호출한다.


__repr__ 

  •  "개발자용"의 디버깅 용도로 작성된 문자열 표현식이다.
  • 개발자가 객체를 재생성하거나 디버깅할 때 유용한 정보를 포함하는 것이 일반적이다.
  • __str__ 메서드가 정의되지 않았거나 호출하는 코드에서 repr() 함수를 사용한 경우, 파이썬은 __repr__ 메서드를 호출한다.

 

eval과 같이 사용시 주의점

위에 "개발자가 객체를 재생성하거나" 라고 강조를 하였다. 그 이유는 eval(repr(obj)) 표현식으로 함수를 호출하면 객체를 재생성할 수 있기때문이다.
 
 

간단한 예제를 통해 증명해보자

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

    def __str__(self):
        return f"Point({self.x}, {self.y})"

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

 
아래와 같이 호출 우선 순위와 출력 결과를 확인해보자

point = Point(1, 2)

print(str(point))  # Output: Point(1, 2) (__str__ 호출)
print(repr(point)) # Output: Point(x=1, y=2) (__repr__ 호출)
print(point)       # Output: Point(1, 2) (__str__ 호출)

 
eval을 사용했을 때 아래처럼 객체가 재생성되는 것을 볼 수 있다.
외부 입력으로부터 문자열을 eval()에 전달하면, 해당 문자열이 임의의 파이썬 코드로 실행될 수 있으며, 이는 보안 취약점으로 이어질 수 있기때문에 항상 주의가 필요하다.

point_repr = repr(point)  # Output: Point(x=1, y=2) (__repr__ 호출)
new_point = eval(point_repr)  # Point 객체를 eval함수로 재생성
print(type(new_point))  # Output: <class '__main__.Point'> (객체 재성성됨)
print(new_point) # Output: Point(1, 2) (__str__ 호출)

 
 

728x90
반응형