__str__과 __repr__의 차이점

python magic-methods repr


파이썬에서 __str____repr__ 의 차이점은 무엇입니까 ?




Answer 1 moshez


Alex 는 잘 요약했지만 놀랍게도 너무 간결했습니다.

먼저 Alex의 게시물의 요점을 반복하겠습니다 .

  • 기본 구현은 쓸모가 없습니다 (그렇지 않은 것을 생각하기는 어렵지만 예)
  • __repr__ 목표는 모호하지 않은 것입니다
  • __str__ 목표는 읽을 수있는 것입니다
  • 컨테이너의 __str__ 은 포함 된 객체의 __repr__ 을 사용합니다.

기본 구현은 쓸모가 없습니다

파이썬의 기본값이 상당히 유용한 경향이 있기 때문에 이것은 대부분 놀랍습니다. 그러나이 경우 __repr__ 의 기본값은 다음과 같습니다.

return "%s(%r)" % (self.__class__, self.__dict__)

너무 위험했을 것입니다 (예를 들어, 객체가 서로 참조하면 무한 재귀에 들어가기가 너무 쉽습니다). 그래서 파이썬은 대처합니다. true 인 한 가지 기본값이 있습니다. __repr__ 이 정의되어 있고 __str__ 이 아닌 경우 객체는 __str__=__repr__ 처럼 동작합니다 .

즉, 구현하는 거의 모든 객체 에는 객체를 이해하는 데 사용할 수 있는 기능적인 __repr__ 이 있어야 합니다. __str__ 구현 은 선택 사항입니다. "예쁜 인쇄"기능 (예 : 보고서 생성기에서 사용)이 필요한 경우 수행하십시오.

__repr__ 의 목표는 모호하지 않은 것입니다

디버거를 믿지 않습니다. 디버거를 사용하는 방법을 모르고 심각하게 사용한 적이 없습니다. 또한 디버거의 가장 큰 결함은 기본 특성이라고 생각합니다. 오랫동안 디버깅 한 대부분의 실패는 멀리 떨어진 은하계에서 일어났습니다. 이것은 내가 종교적 열정으로 벌목을 믿는다는 것을 의미합니다. 로깅은 모든 불합격 서버 시스템의 생명력입니다. 파이썬은 쉽게 로깅 할 수 있습니다 : 어쩌면 프로젝트 특정 래퍼로 필요한 것은

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

그러나 마지막 단계를 수행해야합니다. 구현하는 모든 객체에 유용한 repr이 있는지 확인하십시오. 따라서 이와 같은 코드는 작동 할 수 있습니다. 은 "평가"일이 온다 이유입니다 : 당신이 그렇게 충분한 정보가있는 경우 eval(repr(c))==c , 당신에 대해 알아야 할 모든 것을 알고있는 수단 c . 그것이 퍼지 방식으로 충분히 쉽다면 그렇게하십시오. 그렇지 않다면 어쨌든 c 에 대한 충분한 정보가 있는지 확인하십시오 . 나는 보통 eval과 같은 형식을 사용합니다 : "MyClass(this=%r,that=%r)" % (self.this,self.that) . 실제로 MyClass를 구성 할 수 있거나 올바른 생성자 인수라는 의미는 아닙니다.“이 인스턴스에 대해 알아야 할 모든 것”을 표현하는 것이 유용한 형식입니다.

참고 : %s 아닌 % %r 사용했습니다 . __repr__ 구현에서 항상 repr() [또는 %r 형식 문자]를 사용 하거나 repr의 목표를 이기고 싶습니다. MyClass(3)MyClass("3") 를 구별 할 수 있기를 원합니다 .

__str__ 의 목표는 읽을 수있는 것입니다

특히, 모호하지 않도록 의도 된 것은 아닙니다. str(3)==str("3") 입니다. 마찬가지로 IP 추상화를 구현하는 경우 str을 192.168.1.1처럼 보이는 것이 좋습니다. 날짜 / 시간 추상화를 구현할 때 str은 "2010/4/12 15:35:22"등이 될 수 있습니다. 목표는 프로그래머가 아닌 사용자가 읽기를 원하는 방식으로 나타내는 것입니다. 쓸모없는 자릿수를 잘라 내고 다른 클래스 인 것처럼 보이십시오. 가독성을 지원하는 한 개선 된 것입니다.

컨테이너의 __str__ 은 포함 된 객체의 __repr__ 을 사용합니다.

놀랍지 않나요? 그것은 약간이지만 __str__ 사용하면 얼마나 읽을 수 있습니까?

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

하지 매우. 특히 컨테이너의 문자열은 문자열 표현을 방해하기가 너무 쉽습니다. 모호함에 직면하여 파이썬은 추측하려는 유혹에 저항합니다. 목록을 인쇄 할 때 위의 동작을 원한다면

print "[" + ", ".join(l) + "]"

(사전에 대해 어떻게해야하는지 알아낼 수도 있습니다.

Summary

구현 하는 모든 클래스에 대해 __repr__ 을 구현하십시오. 이것은 제 2의 본성이어야합니다. 가독성 측면에서 오류가있는 문자열 버전을 사용하는 것이 유용하다고 생각되면 __str__ 을 구현하십시오 .




Answer 2 Ned Batchelder


내 경험 규칙 : __repr__ 은 개발자 를위한 __str__ 은 고객을위한 것입니다.




Answer 3 Alex Martelli


특별히 보장하기 위해 행동하지 않는 한, 대부분의 수업은 다음 중 하나에 대한 유용한 결과를 얻지 못합니다.

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

보시다시피 클래스와 객체의 id 를 넘어서는 아무런 정보도없고 정보도 없습니다 . 둘 중 하나만 재정의하는 경우 ... :

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

당신이 보는대로 오버라이드 (override)하는 경우는, __repr__ , 그것도 위해 사용되는 __str__ 하지만 그 반대의 경우도 마찬가지.

다른 중요한 맛있는 가벼운 음식은 알고 : __str__ 를 A는 내장에 컨테이너 사용에 __repr__ 아니라 __str__ 을 포함 된 항목. 그리고 일반적인 문서에서 발견 된 주제에 대한 단어에도 불구하고, __repr__ 객체를 eval 이 동일한 객체를 만드는 데 사용할 수있는 문자열로 만드는 사람은 거의 없습니다 (너무 어렵고 관련 모듈을 실제로 가져 오는 방법을 모릅니다) 실제로 불가능하다).

따라서 내 충고 : __str__ 을 합리적으로 읽기 쉽고 __repr__ 을 가능한 한 명확하게 만드는 데 __eval__ . 그렇지만 __repr__ 의 반환 값을 __eval__에 대한 입력으로 받아 들일 수 없는 퍼지 불가능한 목표 를 방해합니다 .




Answer 4 Andrew Clark


__repr__ : 파이썬 객체의 표현은 일반적으로 eval이 해당 객체로 다시 변환합니다.

__str__ : 텍스트 형식의 객체라고 생각하는 것입니다.

e.g.

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True



Answer 5 bitoffdev


간단히 말해 __repr__ 의 목표는 분명하고 __str__ 은 읽을 수있는 것입니다.

다음은 좋은 예입니다.

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

repr에 대한이 문서를 읽으십시오.

repr(object)

인쇄 가능한 객체 표현이 포함 된 문자열을 반환합니다. 이것은 변환에 의해 산출 된 값과 같습니다 (역 따옴표). 이 기능에 일반 기능으로 액세스 할 수 있으면 유용합니다. 많은 유형의 경우,이 함수는 eval() 전달 될 때 동일한 값을 가진 객체를 생성하는 문자열을 반환하려고 시도합니다 . 그렇지 않으면 표현은 객체 유형의 이름을 포함하는 꺾쇠 괄호로 묶인 문자열입니다. 종종 객체의 이름과 주소를 포함한 추가 정보가 포함됩니다. 클래스는 __repr__() 메서드를 정의하여이 함수가 인스턴스에 대해 반환하는 것을 제어 할 수 있습니다 .

str에 대한 문서는 다음과 같습니다.

str(object='')

멋지게 인쇄 가능한 객체 표현을 포함하는 문자열을 반환합니다. 문자열의 경우 문자열 자체를 반환합니다. repr(object) 와의 차이점 은 str(object) 가 항상 eval() 허용되는 문자열을 리턴하지는 않는다는 것입니다 . 그것의 목표는 인쇄 가능한 문자열을 반환하는 것입니다. 인수가 없으면 빈 문자열 '' 을 반환합니다 .