print()を使用してクラスのインスタンスを印刷する方法は?


539

私はPythonでロープを学んでいます。関数Foobarを使用してクラスのオブジェクトを印刷しようとすると、次のprint()ような出力が得られます。

<__main__.Foobar instance at 0x7ff2a18c>

クラスとそのオブジェクト印刷動作(または文字列表現)を設定できる方法はありますか?たとえば、クラスオブジェクトを呼び出すと、そのデータメンバーを特定の形式で出力したいと思います。Pythonでこれを実現する方法は?print()

C ++クラスに精通している場合は、クラスのメソッドをostream追加することにより、標準に対して上記を実現できますfriend ostream& operator << (ostream&, const Foobar&)

回答:


629
>>> 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()機能を(またはあなたが対話プロンプトでそれを見たとき)。これが最もPython的な方法ではない場合、私も謝罪します。私もまだ学習しているためですが、それでも機能します。

__str__メソッドが指定されていない場合、Pythonは__repr__代わりに結果を出力します。を定義し__str__、を定義しない場合__repr__、Pythonは上記の表示をとして__repr__使用しますが__str__、印刷には引き続き使用します。


11
Strの代わりに使用できるユニコードメソッドもあります。文字列ではなくUnicodeオブジェクトを返す必要があることに注意してください(ただし、文字列を返す場合、Unicodeへの変換はとにかく行われます...)
kender

@kender-私はそれについて知りませんでしたが、振り返ってみると、Python 2.xの壊れたUnicode処理を考えると、それは完全に理にかなっています。
Chris Lutz、

11
この回答は、この他の回答へのリンクがないと完了できないと思います。
tnotstar 2012

助かりました!ただし、メソッド__repr __(self)を再実装した後、printはユーザーを誤解させます。これに関するベストプラクティスを知っていますか?
ベトナム2013

10
Javaプログラマーにとって:__str __(self)はPythonの世界のtoString()に似ています
Janac Meena

134

Chris Lutzが述べたように、これは__repr__クラスのメソッドによって定義されます。

のドキュメントからrepr()

多くのタイプの場合、この関数は、に渡されたときに同じ値を持つオブジェクトを生成する文字列を返そうとしますeval()。それ以外の場合、表現は、オブジェクトのタイプの名前と追加情報を含む山括弧で囲まれた文字列です。多くの場合、オブジェクトの名前とアドレスが含まれます。クラスは、__repr__()メソッドを定義することにより、この関数がインスタンスに対して返すものを制御できます。

次のクラスTestがあるとします。

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)

..itはPythonシェルで次のように動作します。

>>> 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
クリス・ルッツ

1
エラー、おっと。REPL出力を手動で変更しても、うまく終了しません。私はおそらく私の投稿をdoctestする必要があります:P
dbr

1
%文字列の書式は以下から、非推奨されていないdocs.python.org/whatsnew/2.6.html「%演算子をれる補充方法をフォーマットより強力な文字列形式()によって」
DBR

4
Dbr:それは本当です。「Python 3.0の新機能」ドキュメントにも「format()メソッド[...]と記載されていることに注意してください。最終的には、これを文字列フォーマット用の唯一のAPIにして、Python 3.1での%演算子の廃止を開始する予定です。」
Ashwin Nanjappa

1
Pitty、%さんはとても便利です。
Janusz Lenar 2011

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これらのオブジェクトを再帰的に印刷する方法、またはオブジェクトがあるかどうかを判断する方法を尋ねていますか?
ジョン

13

私の2セントを@dbrの回答に追加するために、彼が引用した公式ドキュメントからこの文を実装する方法の例を次に示します。

"[...] 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
repr及びSTR異なる意味を持っている: のreprは(再)になるPythonのソースであるべきであるが、同じオブジェクトを作成する-これは、あるのreprのコードでesentation。strは、オブジェクトのかなりのユーザーランド文字列である必要があります。
エリックタワーズ

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

Python 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")

Hydrogenクラスを出力するために、私は以下を使用しました:

print(Hydrogen())

これは、Hydrogenの末尾に括弧がないと機能しません。それらは必要です。

これがお役に立てば幸いです。他にご不明な点がありましたらお知らせください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.