Python의 Magic Method - __repr__()와 __str__()
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!