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
반응형