본문 바로가기
파이썬

파이썬의 str과 repr의 차이점

by 왕초보 독학 코딩 2024. 1. 1.

파이썬을 사용하다 보면 str과 repr을 사용하게 되는 경우가 발생한다. 이 두 함수는 주로 디버깅, 로깅 및 사용자 인터페이스에서 객체를 표시하는 데 사용된다. 여기서는 파이썬의 str과 repr이 언제 사용되고, 어떤 기능을 하는 것인지 자세히 알아보자.

 

 

 

str 이란?

str은 사용자가 읽기 쉬운 형태의 문자열을 반환한다. 일반적으로 '사람이 읽을 수 있는 표현'을 생성한다. 

객체를 str 함수에 전달하면 객체를 사람이 읽을 수 있는 표현의 문자열로 반환한다고 생각하면 된다.

 

str은 사람이 읽을 수 있는 표현이라고 하는 이유는 다음 예제 코드를 실행해 보면 알 수 있다. 

two_int_str = str(2)
two_str_str = str("2")

print(two_int_str == "2")  # true
print(two_str_str == "2")  # true

 

정수 2와 문자열 2을 str 함수에 전달하면 동일한 문자열 2가 된다. 사람이 볼 때는 2는 정수인지 문자열인지 구분을 할 필요가 없기 때문이라고 생각할 수 있다.

 

 

 

repr 이란?

repr은 개발자에게 디버깅과 개발 시에 유용한 형태의 문자열을 반환한다. 그 이유로 repr로 반환되는 문자열은 해당 객체를 완벽하게 재현할 수 있게 표현된 문자열을 반환하기 때문이다.

 

객체를 repr 함수에 전달하면 str 함수처럼 문자열이 반환되지만, 정수 2와 문자열 2를 repr 함수에 전달하면 다른 문자열이 된다는 것을 확인할 수 있다.

two_int_repr = repr(2)
two_str_repr = repr("2")

print(two_int_repr == "2")  # true
print(two_str_repr == "'2'")  # true

 

two_int_repr은 "2"이지만, two_str_repr은 two_str에 비해 따옴표로 감싸져 있는 점을 눈여겨보자. 이렇게 따옴표가 감싸져 있는 이유는 two_str_repr은 two_str이 문자열이기 때문이기 때문이다.

 

이렇게 만들어진 two_repr과 two_str_repr을 eval 함수에 전달하면, 해당 문자열을 완벽하게 다시 객체로 재현할 수 있게 된다.

two_int_eval = eval(two_int_repr)
two_str_eval = eval(two_str_repr)

print(two_int_eval == 2)  # true
print(two_str_eval == "2")  # true

 

하지만 str로 만들어진 two_int_str과 two_str_str을 eval 함수에 전달하면, two_int_str은 정수 2로 재현되지만 two_str_str은 문자열 2가 되지 않고 정수 2로 재현된다. 

 

 

 

str과 repr의 차이점

str은 사람이 읽을 수 있게 표현된 문자열이고, repr은 해당 객체를 재현할 수 있는 표현된 문자열이라고 할 수 있다. 이 차이를 한번 더 명확하게 알 수 있게 다른 객체로 확인해 보자.

파이썬에는 날짜를 표현하기 위해 datetime라는 클래스를 제공한다. datetime클래스의 now 메서드는 현재 시간을 표현하는 datetime 객체를 반환한다.

import datetime

now = datetime.datetime.now()

 

이제 now는 이 코드가 실행된 현재 시간을 표현하는 datetime객체가 된다. 

now 객체를 str 함수에 전달하고 print 함수로 출력해 보면 현재 날짜와 시간이 출력되는 것을 볼 수 있다. 2024년 01월 01일 10시 40분 20.334960초로 사람이 쉽게 읽을 수 있게 표현된다.

print(str(now))  # 2024-01-01 10:48:20.334960

 

반면 now 객체를 repr 함수에 전달하면, str 함수와 다르게 표현되는 것을 확인할 수 있다. 

print(repr(now))  # datetime.datetime(2024, 1, 1, 10, 48, 20, 334960)

 

 repr로 만들어진 문자열은 now 객체를 동일하게 만들 수 있는 문자열이 된다.

now_repr_eval = eval(repr(now))

print(now == now_repr_eval)  # True

 

만약 str로 만들어진 문자열로 eval를 실행하면 에러가 발생한다.

>>> eval(str(now))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    2024-01-01 10:48:20.334960
          ^
SyntaxError: leading zeros in decim

 

 

 

사용자 정의 클래스에 str 적용하기

정수(int)나 문자열(str)과 같은 파이썬 내장 클래스들은 str과 repr 함수에 객체를 전달하면 잘 작동하도록 미리 만들어져 있다. 하지만 사용자 정의 클래스의 객체는 str 함수에 전달하여도 잘 작동하지 않는다.

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
zero = Point(0, 0)
print(str(zero))  # <__main__.Point object at 0x7fc0c01b9d60>

 

사용자 정의 클래스의 객체를 str 함수에 전달하면 <__main__.Point object at 0x7fc0c01b9d60> 같은 내용이 출력된다. 이 내용은 해당 객체의 정보와 메모리 정보를 나타낸다.

 

만일 str 함수에서 원하는 대로 작동하게 만들려면 __str__ 메서드를 정의하면 된다. str 함수에 객체를 전달하면 객체의 __str__ 메서드를 호출하기 때문이다.

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "x: {self.x}, y: {self.y}"

 

다시 Point 클래스 객체를 만들어서 str 함수에 전달하면, Point 클래스의 __str__ 메서드가 리턴하는 문자열이 잘 출력되는 것을 확인할 수 있다. zero 객체의 x값과 y값이 0이라는 것을 사용자가 쉽게 확인할 수 있게 되었다.

zero = Point(0, 0)
print(str(zero))  # x: 0, y: 0

 

 

 

사용자 정의 클래스에 repr 적용하기

repr 함수에 객체를 전달하면 __repr__ 메서드가 호출된다. 따라서 사용자 정의 클래스 객체가 repr에서 잘 작동하게 하려면 __repr__ 메서드를 정의하면 된다. __repr__ 메서드는 해당 객체가 완벽하게 재현될 수 있는 문자열을 반환하도록 해야 한다.

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

 

 

zero = Point(0, 0)
print(repr(zero))  # Point(0, 0)

 

 

 

 

str 함수의 작동 방식

str 함수는 객체의 클래스가 __str__ 메서드와 __repr__ 메서드를 어떻게 정의되어 있는지에 따라서 작동 방식이 달라진다.

str 함수는 다음과 같은 순서로 작동한다.

1. __str__ 메서드가 있으면 __str__ 메서드가 호출된다.

2. __str__ 메서드가 없고 __repr__ 메서드가 있으면, __repr__ 메서드가 호출된다.

3. __str__ 메서드와 __repr__ 메서드가 없으면, 객체의 클래스 정보와 메모리 정보가 리턴됨

 

따라서 다음과 같은 결과를 얻을 수 있다.

__str__ 메서드가 정의되고, __repr__ 메서드가 정의되지 않은 경우 -> __str__ 메서드가 호출됨

__str__ 메서드가 정의되지 않고, __repr__ 메서드가 정의된 경우 -> __repr__ 메서드가 호출됨

__str__ 메서드와 __repr__ 메서드가 정의된 경우 -> __str__ 메서드가 호출됨

__str__ 메서드와 __repr__ 메서드가 정의되지 않은 경우 -> 객체의 클래스 정보와 메모리 정보가 리턴됨

'파이썬' 카테고리의 다른 글

파이썬 namedtuple  (1) 2024.01.07
파이썬의 던더 메서드  (0) 2024.01.07
파이썬 언패킹  (0) 2024.01.01