장고로 개발을 하며 model 뚱땡이를 만들던 중 str과 repr이 거의 비슷한 역할을 하는 것을 알게 되었다. 그러다 보니 __str__
을 써야하나 ? __repr__
를 써야하나? 고민에 빠지게 되어 한번 찾아보게 되었습니다.
기본적으로 __repr__
의 출력값은 객체임으로, 객체를 구분 짓는 용도로 쓰는 것 같습니다. 그렇기에 output은 보통 x
class Foo(object):
def __str__(object):
return 'foo'
print repr(Foo()) # (__main__.Sic object at 0x2617f0)
print str(Foo()) # foo
이런식 입니다. __repr__
이 정의가 안되있으면 이런식 생(?) 주소값이 나옵니다. __str__
의 경우 만약 정의가 안되있으면 __repr__
으로 나옵니다.
무튼 repr의 경우는 eval을 통해서 만든 것인데 이미 거기서 부터 안써야 할 것 같은 괜한 불안감이 나옵니다. 사실 전직 js로 node를 짰던 저의 경우 무조건 eval은 피하고 싶었는데 python 역시 eval은…evil
호출하는 위치와 방식에 따라 eval의 실행 컨텍스트와 범위(scope)가 달라짐으로 사실 eval 자체가 보안에 취약한 코드이다. eval이 왜 안좋은 가는 4가지 이유 때문인데
1.충분히 이것을 안쓰고도 좋은 코드를 짤 수 있다. 2.보안적으로 매우 위험하다. 3.debugging을 어렵게 만든다. 4.느리다!
즉 ouput case[OP case]를 제외하고는 안쓰는 게 좋다!
str를 정의하지 않으면 자동으로 repr으로 print 되기때문에 repr먼저 잘 정의하고 그다음에 str을 정의하는 게 좋다는데 그냥 무조건 str을 정의하는게 더 현명한 행동 같다. [특히나,빠르면 repr을 쓸 수 도 있겠지만… eval때문에 느린 repr을 무조건 정의 하는 것 보다는 그냥 str을 쓰는게…]
지금도 그러고 과거에도 계속 str과 repr은 가열차게 싸우는 것 같기도 한데 그치만 어느정도 str이 이긴 것 같은 것은 착각이 아닌 것 같다.
그치만 좀 우리에게 혼란을 주기 좋게 python에서 설명을
object.repr(self) Called by the repr() built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <…some useful description…> should be returned. The return value must be a string object. If a class defines repr() but not str(), then repr() is also used when an “informal” string representation of instances of that class is required. This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.
object.str(self) Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object. This method differs from object.repr() in that there is no expectation that str() return a valid Python expression: a more convenient or concise representation can be used. The default implementation defined by the built-in type object calls object.repr().
이런식으로 한다… 왠지 repr는 official이니 해야할 것 같고… 왠지 googling하면 막 개발자용이라고…
하지만!
print 문과 str () 내장 함수는 __str__
을 사용하여 객체의 문자열 표현을 표시하고 repr () 내장 함수는 __repr__
을 사용하여 객체를 표시한다. 어차피 우리가 쓰려는 __str__
은 print를 위한 것이니… 그냥 이거 쓰는게 좋은 것 같고___str__
을 안하면 __repr__
이 자동으로 되기 때문에 __str__
을 반드시 정의 하는 것이 좋아 보인다.
[기본적으로 __repr__
을 무조건 만들고 그다음에 __str__
은 선택사항! 왜냐면 __str__
이 구현되지 않으면 __repr__
이 호출되니까! 라는 진영도 있는데…음 왜? 그냥 무조건 __str__
을 만들면 되잖아? 라는 생각이 든다] [전문가를 위한 파이썬(꽤 많이 읽히고 python진영에서 effective python같은 존재 인가보다) 에서는 __repr__
를 위와 같은 이유로 권장하는데… 음 아직 왜 그래야하는지 잘 모르겠다…(그치만 나보다 더 잘 아는 사람이 워낙 많으니… 함부로 말하기는 어려운 것)]
참고자료 Stackoverflow: http://stackoverflow.com/a/2626364/504262 글로벌 인구들이 알려주기(?) https://code.i-harness.com/ko/q/15ec1f 한국인들의 알려주기(?)
http://pinocc.tistory.com/168%20%5B%EB%95%85%EB%9A%B1%20%EC%B0%BD%EA%B3%A0%5D https://docs.python.org/3.8/reference/datamodel.html#object.repr%20%EC%B6%9C%EC%B2%98:%20