지식이 늘었다/웹개발

Python의 Magic Method - __repr__()와 __str__()

PurpleGuy101 2024. 12. 16. 16:28

 

0.

(잡설)

메타적이라는 말이 있다

한국어로 번역하면 종종 형이상학적으로 번역이 된다.

윤리학과 메타윤리학, 물리학과 메타물리학..

앞에 메타라는 접두사가 붙는다면,

그 대상자체에 대한 의미를 나타내게 된다.

 

해당 시스템의 존재방식, 

그 시스템안에서 생기는 모순

뭔가 증명불가능하고 뜬구름 잡는것 같은 그런 녀석들

 

가령 우리의 눈은 빨간색, 초록색, 파란색의 빛을 인식하는 세포들이 존재하고

이를 통해 우리는 색을 구분하고 인식할 수 있다.. 라는 논의에서

칸트가 '빨강'이라는 색은 물체의 본질적인 속성인가? 우리는 빨강을 인식하는가..?

하는 인식하는 것은 무엇인가?하는 질문을 던지는 것처럼..

어찌보면 중요한데 어찌보면 뜬구름 잡는 거 같은 기분을 유발한다.

 

처음 __init__ __str__ 같은 녀석들을 보았을 때 

무슨 뜬구름 잡는 소리지..?하는 느낌이 들었다.

 

그렇다고 매직메소드가 메타적이라는 소리는 아닌데

내가 뭔말을 하고 싶었던 거지?

하여튼 매직메소드를 처음봤을 때 

얜 뭐야? 했던 기억이 난다.

 

변수에 값잘넣고 함수만 순서대로 실행하면 되는 파이썬에

갑자기 _ _ 붙은 친구들이 나왔으니 말이다.

 

1.

 

파이썬에서 

두개의 언더스코어 '_' 문자가 붙은 메소드를

특수Special 메소드 혹은 매직Magic 메소드라고 한다.

 

클래스에서 처음 객체를 generate할 때 사용되는

__init__()의 init 메소드처럼 말이다.

 

2.

아래의 코드를 실행해보자.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
bob = Person("Bob", 35)
print(bob)

# 출력 : <__main__.Person object at 0x0000028A64970370>

 

print(bob)을 했을 때,

파이썬은 Object를 표현하는 문자열을 출력한다.

왜냐하면.. 파이썬이 print로 직접 출력할 수 있는게 문자뿐이기 때문이다.

(다르게 보면... 문자열 말고는 print로 뭘 출력할건데?하는 의문이 든다.)

우리가 bob이라는 객체에 대해서 자세히 알고 싶어서 

bob을 print했고...

 

파이썬에서는

객체의 클래스와 저장공간에 대한 정보를 제공하는 것이

문자열 형태의 객체 정보로 적합하다고 생각해서

 

기본적으로 __repr__ 라는 매직메소드를 사용하여

<__main__.Person object at 0x0000028A64970370>

와 같이

클래스이름+메모리주소를 나타내는 문자열을 반환해주는 기능을 달아놨다.

 

이런식으로

문자열로 전달할 수 있는 친절한 설명을 전달해주는 것을

기본기능으로 제공해주는 것.

 

3.

 

객체를 만들고,

아무런 설정을 따로 해주지 않았다면.

__repr__() 메소드가

객체에 대한 설명을 담은 문자열 반환 메소드로 호출된다.

 

우리가 직접 객체에 대한 설명을 지정해서 문자열로 반환해줄 수도 있다.

그것이 __str__() 메서드이다.

이걸로 커스터마이징하면 된다.

 

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f'My name is {self.name}. Nice to meet you!'
    
bob = Person("Bob", 35)
print(bob)

# 출력 : My name is Bob. Nice to meet you!

 

 

4.

 

물론 __repr__() 메소드도

객체에서 직접 정의해줄 수 있다.

print(bob)을 했다면, 여전히 유저친화적인 __str__() 메소드가 호출되지만,

 

나중에 디버거와 같은 개발자를 위한 환경에서

__repr__()메소드가 호출되는 경우가 있으며,

 

객체의 상태를 __str__로 호출하면 상태를 알아보기 애매한(Ambigiuous) 상황에

더 확실하게 객체 상태를 표현하기 위해서 __repr__()를 직접 호출해서 사용하기도한다.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f'My name is {self.name}. Nice to meet you!'
    

    def __repr__(self):
        return f'<Person({self.name}, {self.age})>'

    
bob = Person("Bob", 35)
print(bob) # My name is Bob. Nice to meet you!