etc./StackOverFlow

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

청렴결백한 만능 재주꾼 2021. 10. 9. 02:27
반응형

질문자 :Casebash


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



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

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

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

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

Python의 기본값은 상당히 유용한 경향이 있기 때문에 이것은 대부분 놀라운 일입니다. 그러나 이 경우 __repr__ 대한 기본값은 다음과 같이 작동합니다.

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

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

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

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

바로 나가서 말하겠습니다. 저는 디버거를 믿지 않습니다. 나는 디버거를 어떻게 사용하는지 전혀 모르고 진지하게 사용한 적이 없습니다. 또한 디버거의 가장 큰 결함은 기본 특성이라고 생각합니다. 내가 디버그하는 대부분의 오류는 아주 오래전에 멀리 떨어진 은하계에서 발생했습니다. 이것은 내가 종교적 열정으로 벌목을 믿는다는 것을 의미합니다. 로깅은 모든 적절한 화재 및 잊어버리기 서버 시스템의 생명선입니다. Python을 사용하면 쉽게 기록할 수 있습니다. 일부 프로젝트 특정 래퍼를 사용하면

 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 에 대한 충분한 정보를 가지고 있는지 확인하십시오. 나는 보통 평가와 같은 형식을 사용합니다: "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) + "]"

(아마도 사전에 대해 무엇을 해야 하는지 알 수 있을 것입니다.

요약

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


moshez

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


Ned Batchelder

달리 보장하기 위해 특별히 조치를 취하지 않는 한, 대부분의 클래스는 다음 중 하나에 대해 유용한 결과를 얻지 못합니다.

 >>> 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__ A는 내장에 컨테이너 사용에 __repr__ 아니라 __str__ 포함 된 항목. 그리고 일반적인 문서에서 찾을 수 있는 주제에 대한 단어에도 불구하고 __repr__ eval 이 동일한 객체를 빌드하는 데 사용할 수 있는 문자열로 만드는 사람은 거의 없습니다. 그것은 실제로 불가능합니다).

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


Alex Martelli

__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



__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() 허용되는 문자열을 반환하려고 시도하지는 않는다는 것입니다. 목표는 인쇄 가능한 문자열을 반환하는 것입니다. 인수가 주어지지 않으면 빈 문자열 '' 반환합니다.


bitoffdev

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

__str__ 및 ( "던더 (이중 밑줄) 문자열"과 같이) __repr__ 반환 문자열은 객체의 상태에 따라 것을 모두 특별한 방법이 있습니다 (() "표현"에 대한 "던더 - repper"과 같이).

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

eval 사용하거나 Python 셸에서 문자 대 문자로 입력하여 반환하는 문자열에서 동등한 객체를 다시 __repr__ 할 수 있는 __repr__을 먼저 작성해야 합니다.

나중에 필요할 때 언제든지 사용자가 읽을 수 있는 인스턴스의 문자열 표현을 위해 __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 소스 ) 다음과 같습니다.

 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 객체를 재생성하는 데 필요한 모든 것을 볼 수 있습니다. __repr__ 의해 생성됩니다.

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

datetime 객체를 인쇄하면 사람이 읽을 수 있는 멋진(사실 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 소스 )을 정의하는 방법입니다. 이러한 객체를 재생산하는 데 필요한 모든 속성 때문에 상당히 복잡합니다.

 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 소스 )가 __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__ 정의하십시오.


Aaron Hall

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'

Yong Yang

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

1) __repr__() 은 대화형 파이썬 콘솔에 객체의 이름을 쓰고 엔터를 누르면 호출됩니다.

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

3) __str__ str() 사용하는 모든 함수는 객체의 __repr__() 을 호출합니다.

4) __str__() 은 호출될 때 포함된 요소의 __repr__()

5) __str__() 내에서 호출된 str() 은 잠재적으로 기본 케이스 없이 재귀할 수 있으며 최대 재귀 깊이에서 오류가 발생할 수 있습니다.

6) __repr__() 은 자동으로 무한 재귀를 피하려고 시도하는 repr() 을 호출할 수 ... 대체합니다.


Mangu Singh Rajpurohit

간단히 말해서:

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

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

Fraction 의 문자열 표현이 '(1/2)'이고 객체(Fraction 클래스)가 'Fraction (1,2)'로 표현되는 Fraction 클래스를 만들고 싶다고 가정해 보겠습니다.

따라서 간단한 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)

Zer0

솔직히 말해서 eval(repr(obj)) 은 사용되지 않습니다. eval 사용하는 자신을 발견하면 중지해야 합니다. eval은 위험하고 문자열은 개체를 직렬화하는 데 매우 비효율적인 방법 pickle 사용).

__repr__ = __str__ 설정하는 것이 좋습니다. 그 이유는 str(list) repr 을 호출하기 때문입니다(저는 이것이 Python 3에서 해결되지 않은 Python의 가장 큰 설계 결함 중 하나라고 생각합니다). 실제 repr print [your, objects] 의 출력으로 그다지 도움이 되지 않을 것입니다.

이를 검증하기 위해 내 경험에 따르면 repr 함수의 가장 유용한 사용 사례는 문자열을 다른 문자열 안에 넣는 것입니다(문자열 형식 지정 사용). 이렇게 하면 따옴표나 무엇이든 이스케이프 처리하는 것에 대해 걱정할 필요가 없습니다. 그러나 여기 eval 발생하지 않습니다.


asmeurer

effbot의 (비공식) Python 참조 Wiki(아카이브 사본)에서:

__str__ " 객체의 "비공식적인" 문자열 표현을 계산합니다. 이것은 __repr__ 과 다릅니다. 대신 더 편리하거나 간결한 표현을 사용할 수 있습니다. "


Casebash

Q: __str__()__repr__() 의 차이점은 무엇입니까?

TL;DR: str()/repr()과 __str__()/__repr__()의 차이점

이 질문은 오랫동안 존재해 왔으며 대부분이 정답인 다양한 답변이 있습니다(여러 Python 커뮤니티 전설[!]은 말할 것도 없고요). 그러나 핵심으로 내려오면 이 질문은 str() () 내장 함수와 repr() 나는 내 자신의 말로 차이점을 설명할 것입니다(즉, Core Python Programming 에서 자유롭게 "빌려온" 것이므로 pls 용서해 주십시오).

str()repr() 동일한 기본 직업을 가지고 : 그들의 목표는 파이썬 객체의 문자열 표현을 반환하는 것입니다. 어떤 종류 의 문자열 표현이 그들을 구별하는 것입니다.

  • str() & __str__() 객체의 인쇄 가능한 문자열 표현을 반환합니다... 사람이 읽을 수 있는/사람이 소비할 수 있는 것
  • repr() & __repr__() 은 유효한 Python 객체 인 객체의 문자열 표현을 반환합니다. eval() 전달하거나 오류 없이 Python 셸에 입력할 수 있습니다.

x 문자열을 할당하고 y int 를 할당하고 단순히 각각의 사람이 읽을 수 있는 문자열 버전을 표시해 보겠습니다.

 >>> x, y = 'foo', 123 >>> str(x), str(y) ('foo', '123')

두 경우 모두 따옴표 안에 있는 내용을 그대로 Python 인터프리터에 입력할 수 있습니까? 시도해 보겠습니다.

 >>> 123 123 >>> foo Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'foo' is not defined

분명히 int str 경우는 아닙니다. eval() '123' 을 전달할 수 있지만 'foo' 에서는 작동하지 않습니다.

 >>> eval('123') 123 >>> eval('foo') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 1, in <module> NameError: name 'foo' is not defined

repr() 시도해 보겠습니다. 다시 각 문자열에 대한 따옴표 쌍에 있는 내용을 덤프합니다.

 >>> repr(x), repr(y) ("'foo'", '123') >>> 123 123 >>> 'foo' 'foo'

와우, 둘 다 작동합니까? 그 때문에 'foo' 해당 문자열의 인쇄 가능한 캐릭터 라인 표현, 그것은 평가 가능 아니지만,하지만 "'foo'" 입니다. 123 str() 또는 repr() 의해 호출되는 유효한 Python int 입니다. eval() 을 호출하면 어떻게 될까요?

 >>> eval('123') 123 >>> eval("'foo'") 'foo'

123'foo' 가 유효한 Python 객체이기 때문에 작동합니다. 또 다른 핵심 사항은 때때로 둘 다 같은 것을 반환하지만(동일한 문자열 표현) 항상 그런 것은 아니라는 것입니다. (그리고 예, 예, eval() foo 만들 수 있지만 그게 요점이 아닙니다.)

두 쌍에 대한 더 많은 사실

  1. 때때로, str()repr() 들이 사용자를 대신 호출하고 의미를 암시 적으로 호출됩니다 사용자가 실행 print (Py1 / Py2) 또는 전화 print() 사용자가 호출하지 않더라도, (Py3 +) str() 명시적으로 이러한 호출은 개체가 표시되기 전에 대신 만들어집니다.
  2. Python 셸(대화형 인터프리터)에서 >>> 프롬프트에 변수를 입력하고 RETURN을 누르면 인터프리터는 해당 객체에 대해 암시적으로 호출된 repr()
  3. str()repr()__str__()__repr__() 에 연결하려면 내장 함수, 즉 str(x) 또는 repr(y) 호출이 객체의 해당하는 특수 메서드 x.__str__() 또는 y.__repr()__
  4. 구현함으로써 __str__()__repr__() 파이썬 클래스, 당신은 내장 함수 (오버로드 str()repr() 당신의 클래스의 인스턴스가 전달 될 수 있도록) str()repr() . 그러한 호출이 이루어지면 그들은 돌아서서 클래스의 __str__()__repr__() 호출합니다(#3에 따라).

wescpy

str - 주어진 객체로부터 새로운 문자열 객체를 생성합니다.

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

차이점들:

str():

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

repr():

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

Inconnu

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

  • __str__ 목표 : 사람이 읽을 수 있음
  • __repr__ 목표 eval 통해 기계가 읽을 수 있음

불행히도 Python REPL과 IPython은 REPL 콘솔에서 객체를 인쇄 __repr__ 을 사용하기 때문에 이러한 구분에는 결함이 있습니다 (PythonIPython 관련 질문 참조). 따라서 대화형 콘솔 작업(예: Numpy 또는 Pandas)을 대상으로 하는 프로젝트는 위의 규칙을 무시하고 대신 __repr__


bluenote10

Fluent Python 책에서 :

Python 객체에 대한 기본 요구 사항은 디버깅 및 로깅에 사용되는 문자열 표현과 최종 사용자에게 표시하는 데 사용되는 문자열 표현을 제공하는 것입니다. 그렇기 때문에
특수 메소드 __repr____str__ 이 데이터 모델에 존재합니다.


Ijaz Ahmad Khan

__str____repr__ 의 차이점을 다루고 있습니다. 전자는 최종 사용자도 읽을 수 있고 후자는 개발자에게 최대한 유용합니다. __repr__ 의 기본 구현은 개발자에게 유용한 정보를 생략 하기 때문에 이 목표를 달성하지 못하는 경우가 많습니다.

__str__ 충분히 간단한 경우 일반적으로 다음과 같이 두 세계의 장점을 최대한 활용하려고 합니다.

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

orome

__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

prosti

명심해야 할 한 가지 중요한 점은 컨테이너의 __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))"

Python은 가독성보다 명확성을 선호 합니다. tuple__str__ 호출은 포함된 객체의 __repr__ , 객체의 "정식" 표현을 호출합니다. 공식 표현은 비공식 표현보다 읽기 어렵지만 명확하고 버그에 대해 더 강력합니다.


zangw

간단히 말해서:

 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'

ShadowWalker

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

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


BattleDrum

__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

이 정보가 더 많은 답변을 탐색할 수 있는 구체적인 기반을 구축하는 데 도움이 되기를 바랍니다.


AbstProcDo

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

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


Sampath

__repr__ printstr 메서드를 제외한 모든 곳에서 사용됩니다 __str__ 이 정의된 경우 !)


techkuz

모든 개체는 모든 개체가 만든 기본 클래스에서 __repr__

 class Person: pass p=Person()

repr(p) 을 호출하면 다음을 기본값으로 얻을 수 있습니다.

 <__main__.Person object at 0x7fb2604f03a0>

str(p) 를 호출하면 동일한 출력을 얻을 수 있습니다. __str__ 이 존재하지 않을 __repr__ 호출하기 때문입니다.

우리 자신의 __str__

 class Person: def __init__(self,name,age): self.name=name self.age=age def __repr__(self): print("__repr__ called") return f"Person(name='{self.name}',age={self.age})" p=Person("ali",20)

print(p)str(p) 반환

 __repr__ called Person(name='ali',age=20)

__str__() 추가합시다

 class Person: def __init__(self, name, age): self.name = name self.age = age def __repr__(self): print('__repr__ called') return f"Person(name='{self.name}, age=self.age')" def __str__(self): print('__str__ called') return self.name p=Person("ali",20)

print(p) 및 str(p)를 호출 __str__() 호출하여 반환합니다.

 __str__ called ali

repr(p) 이 반환됩니다.

"Person(name='ali, age=self.age')"이라는 repr

__repr__ 생략 __str__ 만 구현합시다.

 class Person: def __init__(self, name, age): self.name = name self.age = age def __str__(self): print('__str__ called') return self.name p=Person('ali',20)

print(p) __str__ 을 찾고 다음을 반환합니다.

 __str__ called ali

참고= __repr____str__ 정의된 경우 f'name is {p}' __str__ 을 호출합니다.


Yilmaz

이 코드에서 통찰력을 얻을 수 있습니다.

 class Foo(): def __repr__(self): return("repr") def __str__(self): return("str") foo = Foo() foo #repr print(foo) #str

JonnyRobbie

출처 : http:www.stackoverflow.com/questions/1436703/what-is-the-difference-between-str-and-repr

반응형