__str__과 __repr__의 차이점은 무엇입니까?


답변:


2723

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를 구성 할 수 있거나 이것이 올바른 생성자 인수라는 것을 의미하지는 않지만“이 인스턴스에 대해 알아야 할 모든 것”을 나타내는 유용한 형식입니다.

참고 : %r위가 아닌을 사용했습니다 %s. 구현 내에서 항상 repr()[또는 같은 %r형식의 문자] 를 사용 하거나 __repr__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) + "]"

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

요약

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


154
디버깅이 진행되지 않는다는 귀하의 의견에 완전히 동의하지 않습니다. 개발을 위해서는 프로덕션 용도 로깅을 위해 디버거 (및 / 또는 로깅)를 사용하십시오. 디버거를 사용하면 문제가 발생했을 때 발생한 모든 문제를 볼 수 있습니다. 당신은 전체 그림을 볼 수 있습니다. 모든 것을 기록하지 않으면 얻을 수 없습니다. 또한 모든 것을 기록하는 경우 원하는 데이터를 얻기 위해 수많은 데이터를 처리해야합니다.
사무엘

21
좋은 대답 (디버거를 사용하지 않는 것에 대한 비트 제외). 파이썬 3의 str vs unicode대한 다른 Q & A에 대한 링크를 추가하고 싶습니다 . 이는 스위치를 만든 사람들의 토론과 관련이 있습니다.
ThatAintWorking 2016 년

11
디버거의 경우 plus1은 쓸모가 없으며 가치가 없습니다. 대신 로깅 처리량을 늘리십시오. 그리고 예, 이것은 잘 작성된 게시물이었습니다. __repr__디버깅에 필요한 것으로 나타 났습니다 . 도와 주셔서 감사합니다.
personal_cloud

7
디버거는 어리 석음을 제외하고, 나는 % r을 알게하고는 투표 어쨌든 가치
미키 Perlstein을

6
디버거에서 vs 디버거에서 : 그러한 확고한 의견을 얻지 마십시오. 일부 응용 프로그램에서는 디버깅이 현실적이지 않습니다. 일반적으로 실시간이 포함되어 있거나 코드가 액세스가 거의 없거나 콘솔이없는 플랫폼에서만 원격으로 실행되는 경우입니다. 다른 대부분의 경우 수천 줄의 로깅을 수행 할 필요가 없기 때문에 (예 : 디스크를 어지럽히고 응용 프로그램 속도를 늦출 수 있음) 예외를 조사하거나 중단 점을 설정하는 것이 훨씬 빠릅니다. 마지막으로, 예를 들어 임베디드 장치에 로깅하는 것이 항상 가능한 것은 아니며 디버거도 친구입니다.
RedGlyph

523

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


2
obj = uuid.uuid1 ()의 경우, obj .__ str __ ()은 "2d7fc7f0-7706-11e9-94ae-0242ac110002"이고 obj .__ repr __ ()은 "UUID ( '2d7fc7f0-7706-11e9-94ae-0242ac110002)이므로 ')'. 개발자는 (가치 + 원산지)가 필요하지만 고객은 가치가 필요하며 어떻게 가치를 얻는 지 신경 쓰지 않습니다!
Naren Yellavula

1
여기서 고객 이 반드시 최종 사용자를 의미하지는 않습니다. 개체의 클라이언트 또는 사용자입니다. 따라서 SDK 인 경우 SDK 개발자는 __str__일반 개발자가 읽을 수있는 객체를 갖도록합니다. 반면에 __repr__SDK 개발자를위한 것입니다.
Shiplu Mokaddim

398

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

>>> 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>
>>> 

보시 __repr__다시피, 재정의 하면에도 사용 __str__되지만 그 반대도 아닙니다.

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

그래서, 내 조언 : 만들기에 초점을 __str__합리적인 사람이 읽을 수있는, 그리고 __repr__만드는 퍼지 달성 할 수없는 목표로 그를 방해이 경우에도, 당신이 가능하게 할 수있는만큼 명백한 __repr__'에 대한 입력으로 허용 값을 반환 s의 __eval__!


34
단위 테스트에서 나는 항상 eval(repr(foo))같은 객체로 평가 되는지 확인합니다 foo. 당신은 내 테스트 케이스하지 작업 외부 나는 모듈이 가져 오는 방법을 모르는 것이기 때문에 그 권리,하지만이 최소한 보장하지만 그것을가에 작동하는지 몇 가지 예측 가능한 상황. 나는 이것이 결과 __repr__가 충분히 명백한 지를 평가하는 좋은 방법이라고 생각합니다 . 단위 테스트에서이 작업을 수행하면 __repr__클래스가 변경 되었는지 확인할 수 있습니다.
Steven T. Snyder

4
나는 항상 eval(repr(spam)) == spam(적어도 올바른 맥락에서) 또는을 eval(repr(spam))올리 려고 노력 합니다 SyntaxError. 그렇게하면 혼란을 피할 수 있습니다. (그리고 그건 거의 경우, 예를 들어, 재귀 목록, 내장 매크로에 대한 사실과를 제외하고는 다음 stdlib의 대부분 a=[]; a.append(a); print(eval(repr(a)))을 제공합니다 [[Ellipses]]물론 사실에 그렇게하지 않습니다 ...) 사용하는 eval(repr(spam)) 단위 테스트의 전성 검사를 제외하고 ...하지만 않는 때로는 복사 및 붙여 넣기 repr(spam)대화 형 세션으로.
abarnert

왜 컨테이너 (리스트, 튜플) __str__대신 각 요소에 사용하지 __repr__않습니까? __str__내 객체에서 읽을 수 있도록 구현 했을 때 나에게 명백한 것처럼 보이며 목록의 일부인 경우 추악한 것을 볼 수 __repr__있습니다.
SuperGeo

eval(repr(x))내장 유형에서도 실패 하는 사실과 관련된 성가신 버그가 발생 class A(str, Enum): X = 'x'했습니다 eval(repr(A.X)). SyntaxError on on . 슬프지만 이해할 수 있습니다. BTW는 eval(str(A.X))실제로 작동하지만 class A범위 내에있는 경우에만 작동 하므로 유용하지 않을 수 있습니다.
최대

@SuperGeo 다른 답변은 이것을 str사용 합니다 : container use element reprbecause [1, 2, 3]! = ["1", "2, 3"].
mtraceur

163

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

__str__: 당신이 생각하는 것은 텍스트 형태의 객체입니다.

예 :

>>> 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

151

요컨대, 목표는 __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(). 그것의 목표는 인쇄 가능한 문자열을 반환하는 것입니다. 인수가 없으면 빈 문자열을 반환합니다 ''.


1
여기서 인쇄 가능한 문자열의 의미는 무엇입니까? 설명해 주시겠습니까?
Vicrobot

115

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

__str__( "dunder (이중 밑줄) 문자열"로 __repr__읽음 ) 및 ( "dunder-repper"( "표현"의 경우)로 읽음)는 모두 객체의 상태에 따라 문자열을 반환하는 특수한 방법입니다.

__repr____str__누락 된 경우 백업 동작을 제공합니다 .

따라서 먼저 파이썬 쉘에서 문자를 __repr__사용 eval하거나 문자를 입력 하여 반환하는 문자열에서 동등한 객체를 다시 인스턴스화 할 수있는를 작성해야합니다 .

나중에 언제든지 __str__필요하다고 생각 될 때 인스턴스의 사용자가 읽을 수있는 문자열 표현을 위해를 작성할 수 있습니다.

__str__

객체를 인쇄하거나 전달하는 경우합니다 format, str.format또는 str하는 경우 다음 __str__메소드가 정의되고, 그 메소드가 호출 될 것이다, 그렇지 않으면 __repr__사용됩니다.

__repr__

__repr__메소드는 내장 함수에 의해 호출되며 repr객체를 리턴하는 표현식을 평가할 때 파이썬 쉘에서 에코됩니다.

에 대한 백업을 제공하므로 __str__하나만 쓸 수 있으면__repr__

다음은 내장 도움말입니다 repr.

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

즉, 대부분의 객체에서로 인쇄 된 내용을 입력 repr하면 동등한 객체를 만들 수 있어야합니다. 그러나 이것은 기본 구현이 아닙니다.

기본 구현 __repr__

기본 객체 __repr__는 ( C Python source )입니다.

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

즉, 기본적으로 객체가 속한 모듈, 클래스 이름 및 메모리에서 해당 위치의 16 진수 표현을 인쇄합니다. 예를 들면 다음과 같습니다.

<__main__.Foo object at 0x7f80665abdd0>

이 정보는 그다지 유용하지는 않지만 주어진 인스턴스를 정식으로 표현할 수있는 방법을 도출 할 수있는 방법이 없으며, 적어도 메모리에서 고유하게 식별 할 수있는 방법을 알려주는 것이 좋습니다.

어떻게 __repr__유용 할 수 있습니까?

파이썬 쉘과 datetime객체를 사용하여 얼마나 유용한 지 살펴 보자 . 먼저 datetime모듈 을 가져와야합니다 .

import datetime

datetime.now쉘 을 호출 하면 동등한 datetime 객체를 재생성하는 데 필요한 모든 것을 볼 수 있습니다. 이것은 datetime에 의해 작성됩니다 __repr__.

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

날짜 / 시간 객체를 인쇄하면 사람이 읽을 수있는 형식 (실제로는 ISO)으로 표시됩니다. 이것은 datetime에 의해 구현됩니다 __str__.

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

__repr__출력 에서 복사하여 붙여 넣은 다음 인쇄 하여 변수에 할당하지 않았기 때문에 잃어버린 객체를 재생성하는 것은 간단 합니다. 다른 객체와 동일한 사람이 읽을 수있는 출력으로 가져옵니다.

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

그것들을 어떻게 구현합니까?

개발 중에는 가능한 한 동일한 상태에서 객체를 재현 할 수 있어야합니다. 예를 들어, 이것은 datetime 객체가 정의하는 방식입니다 __repr__( Python source ). 이러한 객체를 재생산하는 데 필요한 모든 속성으로 인해 상당히 복잡합니다.

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return s

객체가 사람이 읽을 수있는 표현을 갖기를 원하면 __str__다음에 구현할 수 있습니다 . datetime 객체 ( Python source )가 구현 하는 방법은 다음과 같습니다. __str__이미 ISO 형식으로 표시하는 기능이 있기 때문에 쉽게 수행 할 수 있습니다.

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

설정 __repr__ = __str__?

이것은 설정을 제안하는 또 다른 대답에 대한 비판입니다 __repr__ = __str__.

설정 __repr__ = __str__어리석은 것은 - __repr__에 대한 대체입니다 __str__하고는 __repr__, 작성해야 디버깅 개발자 사용을 위해 작성 당신은 쓰기 전에 __str__.

__str__객체의 텍스트 표현이 필요한 경우 에만 필요합니다.

결론

__repr__작성하는 객체를 정의 하여 개발할 때 사용할 때와 다른 개발자가 재현 할 수있는 예를 갖도록합니다. __str__사람이 읽을 수있는 문자열 표현이 필요한시기를 정의하십시오 .


그것은 라인을 따라 뭔가되어야합니까 type(obj).__qualname__?
Solomon Ucko

파이썬 3에서는 @SolomonUcko가 그렇습니다. 이것이 구현되는 소스 코드를 찾아 내고 함께 얻을 때 그 정보로 답변을 업데이트 할 것입니다.
Aaron Hall

33

Hans Petter Langtangen의 컴퓨팅 과학위한 Python 스크립팅 책 358 페이지에 다음과 같이 명시되어 있습니다.

  • __repr__객체의 완전한 문자열 표현을 목표로;
  • __str__인쇄를위한 좋은 문자열을 반환하는 것입니다.

그래서 저는 그것들을

  • repr = 재생산
  • str = 문자열 (표현)

파이썬을 배울 때 내가 잘못 이해했지만 사용자의 관점에서.

작지만 좋은 예는 다음과 같은 페이지에 있습니다.

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'

pg에 있습니다. # 351.
jiten December

4
repr재생산이라고하는 것은 오해의 소지가 있습니다. 그것을 대표하는 것으로 생각하는 것이 좋습니다.
NelsonGon 2016 년

31

주어진 모든 답변 외에도 몇 가지 사항을 추가하고 싶습니다.

1) __repr__()대화 형 파이썬 콘솔에서 단순히 객체 이름을 쓰고 Enter 키를 누르면 호출됩니다.

2) __str__()print 문과 함께 object를 사용할 때 호출됩니다.

3) __str__누락 된 경우 객체의 str()호출 __repr__()을 사용하여 인쇄 및 기능을 수행하십시오 .

4) __str__()컨테이너의 호출시 __repr__()포함 된 요소의 메소드를 실행 합니다.

5) str()within을 호출 __str__()하면 기본 사례없이 재귀가 발생할 수 있으며 최대 재귀 수준에 오류가 발생할 수 있습니다.

6) __repr__()호출 repr()하면 이미 반복 된 객체를로 대체하여 무한 재귀를 자동으로 피할 수 있습니다 ....


14

간단히 말해 :

__str__는 다른 사람이 쉽게 읽을 수 있도록 객체의 문자열 표현을 표시하는 데 사용됩니다 .

__repr__의 캐릭터 라인 표현을 표시하는 데 사용됩니다 개체를.

Fraction분수의 문자열 표현이 '(1/2)'이고 객체 (Fraction class)가 'Fraction (1,2)'로 표현 되는 클래스 를 만들고 싶다고 가정 해 봅시다.

간단한 Fraction 클래스를 만들 수 있습니다.

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)

13

모든 정직에서 eval(repr(obj))결코 사용되지 않습니다. 자신이 그것을 사용하는 것을 발견하면 eval위험 하기 때문에 문자열을 중지해야합니다. 문자열은 객체를 직렬화하는 매우 비효율적 인 방법입니다 ( pickle대신 사용하십시오).

따라서 설정을 권장합니다 __repr__ = __str__. 그 이유는 요소 를 str(list)호출하기 때문입니다 repr(파이썬 3에서 다루지 않은 파이썬의 가장 큰 디자인 결함 중 하나라고 생각합니다). 실제로 repr는의 출력으로 큰 도움이되지 않을 것입니다 print [your, objects].

이것을 검증하기 위해 필자의 경험에서 가장 유용한 repr함수 사용 사례 는 문자열을 다른 문자열 안에 넣는 것입니다 (문자열 형식 사용). 이런 식으로, 당신은 따옴표 또는 이스케이프 처리에 대해 걱정할 필요가 없습니다. 그러나 eval여기서는 일어나지 않습니다 .


19
나는 이것이 요점을 그리워한다고 생각합니다. 사용은 eval(repr(obj))온 전성 테스트와 경험 법칙입니다-이것이 원래의 객체를 올바르게 재생성하는 경우 적절한 __repr__구현이 있습니다. 실제로 이런 식으로 객체를 직렬화하려는 것은 아닙니다.
jwg

7
eval본질적으로 위험하지 않습니다. 보다 더 위험하지 unlink, open또는 파일에 쓰기. 악의적 인 공격이 임의의 파일 경로를 사용하여 내용을 넣을 수 있기 때문에 파일 쓰기를 중단해야합니까? 멍청한 사람들이 멍청하게 사용하면 모든 것이 위험합니다. 바보는 위험하다. 독촉-크루거 효과는 위험합니다. eval그냥 기능입니다.
Luis Masuelli 2016 년


10

str -주어진 객체에서 새 문자열 객체를 만듭니다.

repr -객체의 표준 문자열 표현을 반환합니다.

차이점들:

str () :

  • 객체를 읽을 수있게한다
  • 최종 사용자를위한 출력 생성

repr () :

  • 객체를 재생산하는 코드가 필요하다
  • 개발자를위한 출력 생성

8

다른 답변에서 누락 된 한 가지 측면. 일반적으로 패턴은 다음과 같습니다.

  • 목표 __str__: 사람이 읽을 수있는
  • 목표 __repr__: 모호하지 않고, 아마도 기계 판독 가능eval

불행히도, 파이썬 REPL과 IPython __repr__이 REPL 콘솔에서 객체를 인쇄 하는 데 사용 하기 때문에이 차별화에 결함이 있습니다 ( PythonIPython 관련 질문 참조 ). 따라서 대화 형 콘솔 작업 (예 : Numpy 또는 Pandas)을 대상으로하는 프로젝트는 위의 규칙을 무시 __repr__하고 대신 사람이 읽을 수있는 구현을 제공하기 시작했습니다 .


7

Fluent Python 책에서 :

Python 객체의 기본 요구 사항은 디버깅 및 로깅에 사용되는 문자열 표현과 최종 사용자에게 프레젠테이션에 사용되는 문자열 표현을 제공하는 것입니다. 이유입니다
특별한 방법 __repr____str__데이터 모델에 존재합니다.


5

훌륭한 답변은 이미 __str__와 의 차이점을 다루고 __repr__있습니다. 내가의 기본 구현 찾을 것을 감안할 때 __repr__종종 그것 때문에이 목표를 달성하는 데 실패 생략 개발자들에게 유용한 정보를.

이런 이유로, 내가 충분히 간단하다면 __str__, 나는 일반적으로 다음과 같은 두 가지 장점을 최대한 활용하려고 노력합니다.

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))

4

명심해야 할 중요한 한 가지는 컨테이너의 __str__사용에 포함 된 객체 가 있다는 것입니다 __repr__.

>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"

파이썬은 가독성을 통해 모호성을 선호__str__의 전화 tuple통화 포함 된 객체 ' __repr__"공식" 객체의 표현입니다. 공식적인 표현은 비공식적 인 표현보다 읽기가 어렵지만, 모호하지 않고 버그에 대해 더 강력합니다.


__repr__ ( __str__)가 정의되어 있지 않을 때 사용합니다 ! 그래서 당신은 틀 렸습니다.
jiten December

4

간단히 말해서 :

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'

4
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

원시 번호 print()의 결과에가 호출 되면 이 decimal.Decimal(23) / decimal.Decimal("1.05")인쇄됩니다. 이 출력은 문자열 형식으로 되어 있습니다 __str__(). 단순히 표현식을 입력하면 decimal.Decimal출력 을 얻습니다. 이 출력은로 표현할 수있는 표현 형식 입니다 __repr__(). 모든 Python 객체에는 두 가지 출력 형식이 있습니다. 문자열 형식은 사람이 읽을 수 있도록 설계되었습니다. 표현 형식은 파이썬 인터프리터에 공급되는 경우 (가능한 경우) 표현 된 객체를 재생산하는 출력을 생성하도록 설계되었습니다.


4

__str__호출하여 객체에서 호출 할 수 있으며 str(obj)사람이 읽을 수있는 문자열을 반환해야합니다.

__repr__호출하여 객체에서 호출 할 수 있으며 repr(obj)내부 객체 (객체 필드 / 속성)를 반환해야합니다.

이 예제는 도움이 될 수 있습니다.

class C1:pass

class C2:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

class C3:        
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")

class C4:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")


ci1 = C1()    
ci2 = C2()  
ci3 = C3()  
ci4 = C4()

print(ci1)       #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1))  #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2)       #C2 class str
print(str(ci2))  #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3)       #C3 class repr
print(str(ci3))  #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4)       #C4 class str 
print(str(ci4))  #C4 class str 
print(repr(ci4)) #C4 class repr

3

그것들을 이해 __str__하고 __repr__직관적이고 영구적으로 구별합니다.

__str__눈을 쉽게 읽을 수 있도록 주어진 객체의 문자열 위장 된 몸통을
__repr__반환합니다.

예를 참조하십시오

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

에 관해서 __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

__repr__결과 에 대해 산술 연산을 편리하게 수행 할 수 있습니다 .

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

작업을 적용하면 __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

오류 만 반환합니다.

또 다른 예.

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

이것이 더 많은 해답을 찾기 위해 구체적인 근거를 구축하는 데 도움이되기를 바랍니다.


3
  1. __str____repr__파이썬 표현식을 반환 할 수 있지만 문자열 객체를 반환해야합니다 .
  2. 경우 __str__구현이 다음 누락 된 __repr__기능은 대체로 사용됩니다. __repr__함수 구현이 누락 된 경우 폴 백이 없습니다.
  3. __repr__함수가 객체의 문자열 표현을 반환하는 경우 함수 구현을 건너 뛸 수 있습니다 __str__.

출처 : https://www.journaldev.com/22460/python-str-repr-functions


2

__repr__by printstr메소드를 제외한 모든 곳에서 사용됩니다 (a __str__가 정의 된 경우!)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.