__str__ 및 __repr__의 목적은 무엇입니까?


82

나는 파이썬에서 어디에 __str__있고 __repr__사용 되는지 정말로 이해하지 못합니다 . 즉 __str__, 객체의 문자열 표현 을 반환합니다. 하지만 왜 그게 필요할까요? 어떤 사용 사례 시나리오에서? 또한 사용에 대해 읽었습니다.__repr__

하지만 내가 이해하지 못하는 것은 어디에서 사용할 것인가?



4
Ruby에서 온 모든 사람에게 tl; dr은 __str__= to_s__repr__= inspect입니다.
Ajedi32

답변:


86

__repr__

repr()내장 함수와 문자열 변환 (역 따옴표)에 의해 호출되어 객체의 "공식적인"문자열 표현을 계산합니다. 가능하다면 이것은 같은 값 (적절한 환경이 주어 졌을 때)을 가진 객체를 다시 만드는 데 사용할 수있는 유효한 파이썬 표현식처럼 보일 것입니다.

__str__

str()내장 함수와 print 문에 의해 호출되어 객체의 "비공식"문자열 표현을 계산합니다.

사용 __str__당신은 클래스가, 당신은 문자열의 일부로이 개체를 사용할 때마다 당신은 유익한 / 비공식 출력을 할 것입니다 경우. 예를 들어 __str__Django 모델에 대한 메소드를 정의 할 수 있으며 이는 Django 관리 인터페이스에서 렌더링됩니다. 대신에 <Model object>사람의 이름과 성, 이벤트의 이름과 날짜 등이 표시됩니다.


__repr__그리고 __str__비슷합니다. 사실 때로는 동일합니다 ( 표준 라이브러리의 BaseSet클래스의 예 sets.py).

def __repr__(self):
    """Return string representation of a set.

    This looks like 'Set([<list of elements>])'.
    """
    return self._repr()

# __str__ is the same as __repr__
__str__ = __repr__

1
감사! 이것이 바로 제가 찾던 것입니다!
다니엘

`return self._repr ()`이하는 일, 코드를 실행하고 이해하려고 할 때 __repr __ ()은 정확히 하나의 인수를 취합니다.
빛나는

그래서 장고 __repr__대신 사용할 수 __str__있습니까?
Amit Tripathi

60

둘 다 많이 사용하는 곳은 대화 형 세션입니다. 개체를 인쇄하면 해당 __str__메서드가 호출되고 개체 만 사용하면 해당 메서드 __repr__가 표시됩니다.

>>> from decimal import Decimal
>>> a = Decimal(1.25)
>>> print(a)
1.25                  <---- this is from __str__
>>> a
Decimal('1.25')       <---- this is from __repr__

__str__(가) 반면, 사람이 읽을 수있는 최대한으로하기위한 것입니다 __repr__개체를 다시 사용할 수있는 뭔가하는 것을 목표로한다 종종이 경우로,이 생성 된 방법을 정확하게하지 않습니다 있지만.

두 가지 모두 __str____repr__동일한 값을 반환하는 것도 드문 일이 아닙니다 (확실히 내장 유형의 경우).


예를 들어 주셔서 감사합니다. 이것이 기본적으로 사용되는 위치에 대한 더 나은 이해를주었습니다
JayRizzo

17

메뚜기, 경우에 의심 산으로 이동고대 교과서를 읽을 . 그것들에서 __repr __ ()은 다음과 같아야합니다 :

가능하다면 동일한 값을 가진 객체를 다시 만드는 데 사용할 수있는 유효한 Python 표현식처럼 보일 것입니다.


6
-1 이것은 유스 케이스가 무엇인지 실제 질문에 대답하려고 시도하지 않기 때문입니다.
Scott Griffiths

4
@Scott : 맞습니다. 그러나 다시 실제 질문 은 처음에 기본 문서로 이동하려는 시도가 전혀 없음을 보여주었습니다. 당신이 스스로 대답을 시도했지만 여전히 그것의 일부 측면에 대해 약간 혼란스러워하는 질문을하는 것과 이와 같은 질문을 게시하는 또 다른 것입니다. 새 질문으로 제목을 입력하는 것만으로도 상위 6 개 제안 된 SO 스레드 중 5 개가 그의 질문에 답했을 것임을 알 수 있지만, 그는 귀찮을 수 없습니다. 나는 그에게 lmgtfy 대답을주지 않았지만 너무 유혹을 받았다.
Peter Rowell

1
실제로 그는에 대해 읽었다 고 말했지만 __repr__공식 문서는 왜 그것을 사용하는지에 대한 질문에 실제로 대답하지 않으며 다른 곳에서 질문에 대한 답변이 있다고해서 그럴만한 이유가 아닙니다. SO에 대한 답변 (인터넷 검색이 아닌 경우 여기로 다시 돌아올 수 있습니다!) 질문에 대한 답변이 가치가 없다고 생각하면 답변 할 수 없습니다.이 경우에는 이미 잘 다루어 졌다는 데 동의합니다. 그래서 중복에 연결하는 것이 적절한 응답이 될 것입니다.
Scott Griffiths

사실, 당신은 틀 렸습니다. 문서는 "이것은 일반적으로 디버깅에 사용되므로 정보가 풍부하고 모호하지 않은 것이 중요합니다."라는 재치로이를 사용하는 이유를 명시 적으로 설명합니다. 나는 너무 많은 포럼 (포럼?)이 Help Vampires의 무게로 가라 앉는 것을 보았고 그것이 그렇게 전달되기 시작하는 것을 보는 것이 나를 고통스럽게합니다. 다른 명백한 SO 답변에 연결하는 것은 제목 줄을 입력 할 때 시작되는 제안 메커니즘의 전체 목적이지만 모든 제안을 무시하기로 결정했습니다. QED 및 PDQ도 있습니다.
Peter Rowell

5
문서는 여전히 디버깅에 사용 하는 방법 을 말하지 않지만 실제로 이것에 대해 논쟁을 벌일 생각은 없었습니다. 우리는 적어도 귀하의 답변이 질문을 다루지 않았다는 데 동의하므로 내 -1은 여전히 ​​나에게 정당하다고 느낍니다. 질문이 잘못 작성되었거나 중복되거나 사소한 경우 질문을 개선하거나 중복에 대한 링크를 제공하거나 단순히 질문에 반대 투표를 할 수 있습니다. 나는 여기서 나의 주된 반대는 답변이 질문에 답해야한다는 것입니다. 질문을 비판하는 다른 메커니즘이 있습니다. 우리 둘 다 여기서 더 좋은 일이 있다고 생각하므로 이제 입을 다물 것입니다.
Scott Griffiths

14

이전 답변을 작성하고 더 많은 예를 보여줍니다. 적절하게 사용하는 경우의 차이 str와는 repr분명하다. 즉 repr반면, 복사 - 붙여 넣은 객체의 정확한 상태를 재 구축 할 수 있습니다 문자열을 반환해야 str하는 데 유용 logging하고 observing디버깅 결과. 다음은 일부 알려진 라이브러리의 다른 출력을 확인하는 몇 가지 예입니다.

날짜 시간

print repr(datetime.now())    #datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
print str(datetime.now())     #2017-12-12 18:49:27.134452

str로그 파일로 인쇄 하는 것이 좋습니다. repr직접 실행하거나 파일에 명령으로 덤프하려는 경우 용도 를 변경할 수 있습니다.

x = datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)

Numpy

print repr(np.array([1,2,3,4,5])) #array([1, 2, 3, 4, 5])
print str(np.array([1,2,3,4,5]))  #[1 2 3 4 5]

Numpy에서는 repr다시 직접 소모품입니다.

Custom Vector3 예제

class Vector3(object):
    def __init__(self, args):
        self.x = args[0]
        self.y = args[1]
        self.z = args[2]

    def __str__(self):
        return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)

    def __repr__(self):
        return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)

이 예제에서는 repr직접 사용 / 실행할 수있는 문자열을 다시 반환하지만 str디버그 출력으로 더 유용합니다.

v = Vector3([1,2,3])
print str(v)     #x: 1, y: 2, z: 3
print repr(v)    #Vector3([1,2,3])

한 가지는 경우, 명심해야 할 str정의되지 않고 repr, str자동으로 호출합니다 repr. 따라서 최소한 정의하는 것이 항상 좋습니다.repr


5

__str__함수 없는 클래스를 만들 수 있습니다.

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

emp1 = Employee('Ivan', 'Smith', 90000)

print(emp1)

이 클래스 인스턴스를 인쇄하면 다음 emp1과 같은 결과를 얻을 수 있습니다.

<__main__.Employee object at 0x7ff6fc0a0e48>

이것은별로 도움이되지 않으며, 우리가 그것을 표시하기 위해 사용하는 경우 (예 : html에서) 인쇄하고자하는 것이 아닙니다.

이제 동일한 클래스이지만 __str__기능이 있습니다.

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

    def __str__(self):
        return(f"The employee {self.first} {self.last} earns {self.pay}.")
        # you can edit this and use any attributes of the class

emp2 = Employee('John', 'Williams', 90000)

print(emp2)

이제 객체가 있음을 인쇄하는 대신 __str__함수 반환으로 지정한 것을 얻습니다 .

The employee John Williams earns 90000


3

str비공식적이고 읽기 쉬운 형식이지만 repr공식적인 객체 표현을 제공합니다.

class Complex:
    # Constructor
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

    # "official" string representation of an object
    def __repr__(self):
        return 'Rational(%s, %s)' % (self.real, self.imag)

    # "informal" string representation of an object (readable)
    def __str__(self):
        return '%s + i%s' % (self.real, self.imag)

    t = Complex(10, 20)

    print (t)     # this is usual way we print the object
    print (str(t))  # this is str representation of object 
    print (repr(t))  # this is repr representation of object   

Answers : 

Rational(10, 20) # usual representation
10 + i20      # str representation
Rational(10, 20)  # repr representation

1

strrepr 은 모두 표현하는 방법입니다. 수업을 작성할 때 사용할 수 있습니다.

class Fraction:
def __init__(self, n, d):
    self.n = n
    self.d = d
def __repr__(self):
    return "{}/{}".format(self.n, self.d)

예를 들어 인스턴스를 인쇄하면 결과가 반환됩니다.

print(Fraction(1, 2))

결과

1/2

동안

class Fraction:
def __init__(self, n, d):
    self.n = n
    self.d = d
def __str__(self):
    return "{}/{}".format(self.n, self.d)
print(Fraction(1, 2))

또한 결과

1/2

그러나 둘 다 작성하면 파이썬이 사용하는 것은 무엇입니까?

class Fraction:
def __init__(self, n, d):
    self.n = n
    self.d = d
def __str__(self):
    return "str"
def __repr__(self):
    return "repr"

print(Fraction(None, None))

결과

str

따라서 파이썬은 실제로 둘 다 작성 될 때 repr 메서드가 아닌 str 메서드를 사용합니다 .


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