print ()를 사용하여 클래스의 인스턴스를 인쇄하는 방법은 무엇입니까?


538

파이썬에서 로프를 배우고 있습니다. 함수를 Foobar사용하여 클래스의 객체를 인쇄하려고 print()하면 다음과 같은 출력이 나타납니다.

<__main__.Foobar instance at 0x7ff2a18c>

클래스객체인쇄 동작 (또는 문자열 표현 )을 설정할 수있는 방법이 있습니까? 예를 들어 클래스 객체를 호출 할 때 데이터 멤버를 특정 형식으로 인쇄하고 싶습니다. 파이썬에서 이것을 달성하는 방법?print()

C ++ 클래스에 익숙한 경우 클래스 ostreamfriend ostream& operator << (ostream&, const Foobar&)메소드를 추가 하여 표준 에 대해 위의 내용을 달성 할 수 있습니다 .

답변:


628
>>> class Test:
...     def __repr__(self):
...         return "Test()"
...     def __str__(self):
...         return "member of Test"
... 
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test

__str__방법은 인쇄시 발생하는 __repr__방식이며, repr()기능 을 사용할 때 (또는 대화식 프롬프트로 보았을 때) 발생 하는 방식입니다 . 이것이 가장 파이썬적인 방법 이 아니라면 여전히 배우고 있기 때문에 사과하지만 작동합니다.

__str__메소드가 제공 되지 않으면 Python은 __repr__대신 결과를 인쇄합니다 . 를 정의 __str__하지만 정의 하지 않으면 __repr__Python은 위에서 본 것을으로 __repr__사용하지만 여전히 __str__인쇄에 사용 합니다.


11
유니 코드 메소드 도 있습니다 . Str 대신 사용할 수 있습니다 . 문자열이 아닌 유니 코드 객체를 반환해야합니다. 그러나 문자열을 반환하면 유니 코드로의 변환이 수행됩니다 ...)
kender

@ 켄더-나는 그것에 대해 몰랐지만, 회고 적으로 파이썬 2.x의 깨진 유니 코드 처리를 고려하면 완벽하게 이해됩니다.
Chris Lutz

11
이 답변은 다른 답변과 연결되지 않으면 완료 될 수 없다고 생각합니다 !
tnotstar

저를 구했습니다! 그러나 __repr __ (self) 메서드를 다시 구현 한 후 인쇄하면 사용자가 오도됩니다. 이 문제에 대한 모범 사례를 알고 있습니까?
Viet

10
자바 프로그래머에게 : __str __ (self)는 파이썬 세계의 toString ()과 같습니다
Janac Meena

134

Chris Lutz가 언급했듯이 이것은 __repr__클래스 의 메소드에 의해 정의됩니다 .

의 문서에서 repr():

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

다음과 같은 클래스 테스트가 주어집니다.

class Test:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return "<Test a:%s b:%s>" % (self.a, self.b)

    def __str__(self):
        return "From str method of Test: a is %s, b is %s" % (self.a, self.b)

.. 그것은 파이썬 쉘에서 다음과 같은 방식으로 작동합니다 :

>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print repr(t)
<Test a:123 b:456>
>>> print(t)
From str method of Test: a is 123, b is 456
>>> print(str(t))
From str method of Test: a is 123, b is 456

__str__메소드가 정의 되지 않은 경우 print(t)(또는 print(str(t))) __repr__대신 결과를 사용합니다.

__repr__정의 된 메소드가 없는 경우 기본값이 사용됩니다.

def __repr__(self):
    return "<%s instance at %s>" % (self.__class__.__name__, id(self))

+1이지만 클래스 코드 __str__는 대화식 쉘의 결과와 다릅니다. : P
Chris Lutz

1
오류, 죄송합니다. REPL 출력을 수동으로 수정하면 결코 끝나지 않습니다. 아마 내 게시물을 doctest해야합니다 : P
dbr

1
%문자열 서식에서 사용되지되지 docs.python.org/whatsnew/2.6.html "% 연산자가되어 보충 ) 방법, 형식 (포맷보다 강력한 문자열"
DBR

4
Dbr : 맞습니다. "Python 3.0의 새로운 기능"문서에도 "format () method [...]라고 나와 있습니다.이 계획은 결국 이것을 문자열 형식화를위한 유일한 API로 만들고 Python 3.1에서 % 연산자를 사용하지 않기 시작하는 것입니다."
Ashwin Nanjappa

1
Pitty는 %매우 편리했습니다.
Janusz Lenar

52

특정 서식없이 모든 클래스에 적용 할 수있는 일반적인 방법은 다음과 같이 수행 할 수 있습니다.

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return str(self.__class__) + ": " + str(self.__dict__)

그리고,

elem = Element('my_name', 'some_symbol', 3)
print(elem)

생산

__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}

23

@Keith 와 같은 상황이라면 다음을 시도해보십시오.

print a.__dict__

그것은 내가 좋은 스타일로 생각하는 것에 반대하지만, 단지 디버그하려고하면 원하는 것을해야합니다.


dict 키에 값에 객체가 있는지 확인하는 방법을 알고 있습니까?
pranaygoyal02

1
@HadoopEvangelist 당신은 그 객체들을 재귀 적으로 인쇄하는 방법을 물어 보거나 객체가 있는지를 결정하고 있습니까?
John

13

@dbr의 답변에 내 2 센트를 추가하기 위해 다음은 그가 인용 한 공식 문서 에서이 문장을 구현하는 방법의 예입니다.

"[...]는 eval ()에 전달 될 때 동일한 값을 가진 객체를 생성하는 문자열을 반환합니다.

이 클래스 정의가 주어지면 :

class Test(object):
    def __init__(self, a, b):
        self._a = a
        self._b = b

    def __str__(self):
        return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)

    def __repr__(self):
        return 'Test("%s","%s")' % (self._a, self._b)

이제 Test클래스 인스턴스를 직렬화하기 쉽습니다 .

x = Test('hello', 'world')
print 'Human readable: ', str(x)
print 'Object representation: ', repr(x)
print

y = eval(repr(x))
print 'Human readable: ', str(y)
print 'Object representation: ', repr(y)
print

마지막 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

그러나 마지막 의견에서 말했듯이 더 많은 정보는 여기에 있습니다 !


12

를 사용해야 __repr__합니다. 이것은 같은 표준 기능 __init__입니다. 예를 들면 다음과 같습니다.

class Foobar():
    """This will create Foobar type object."""

    def __init__(self):
        print "Foobar object is created."

    def __repr__(self):
        return "Type what do you want to see here."

a = Foobar()

print a

2
에 reprSTR은 다른 의미를 가지고 에 repr는 (재) 같은 객체를 생성 할 파이썬 소스해야합니다 -이 그것입니다 에 repr의 코드 esentation; str 은 객체의 사용자 지정 문자열이어야합니다.
Eric Towers

12

@ user394430의 더 아름다운 응답 버전

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return  str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))

elem = Element('my_name', 'some_symbol', 3)
print(elem)

시각적으로 멋진 이름과 값 목록을 생성합니다.

<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3

Ruud 덕분에 더 멋진 버전으로 항목을 정렬합니다.

def __str__(self):
    return  str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))

8

파이썬 3의 경우 :

특정 형식이 중요하지 않은 경우 (예 : 디버깅) 아래의 Printable 클래스에서 상속하십시오. 모든 객체에 대한 코드를 작성할 필요가 없습니다.

답변에서 영감을 얻은

class Printable:
    def __repr__(self):
        from pprint import pformat
        return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)

# Example Usage
class MyClass(Printable):
    pass

my_obj = MyClass()
my_obj.msg = "Hello"
my_obj.number = "46"
print(my_obj)

1

이 스레드에는 이미 많은 답변이 있지만 그중 아무도 나를 도와주지 않았으므로 직접 해결해야했기 때문에이 정보가 조금 더 유익하기를 바랍니다.

수업이 끝날 때 괄호가 있어야합니다. 예 :

print(class())

내가 작업 한 프로젝트의 코드 예는 다음과 같습니다.

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number
    def __str__(self):
        return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number

class Hydrogen(Element):
    def __init__(self):
        super().__init__(name = "Hydrogen", symbol = "H", number = "1")

수소 클래스를 인쇄하기 위해 다음을 사용했습니다.

print(Hydrogen())

수소 끝에서 괄호 없이는 작동하지 않습니다. 그들은 필요합니다.

이것이 도움이 되길 바랍니다. 더 이상 질문이 있으면 알려주십시오.

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