web-dev-qa-db-ja.com

Print()を使用してクラスのオブジェクトを印刷する方法

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

<__main__.Foobar instance at 0x7ff2a18c>

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

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

433
Ashwin Nanjappa
>>> 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() 関数を使うとき(または対話式プロンプトで見るとき)に起こるものです。 Pythonic という方法ではない場合は、まだ勉強しているのでお詫び申し上げます - しかし、それはうまくいきます。

__str__メソッドが与えられていない場合、Pythonは代わりに__repr__の結果を表示します。 __str__を定義し、__repr__を定義しない場合、Pythonは上で見たものを__repr__として使用しますが、それでも印刷には__str__を使用します。

504
Chris Lutz

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)

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))
114
dbr

特定のフォーマットなしで任意のクラスに適用できる一般的な方法は、次のようにして行うことができます。

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}
38
user394430

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

しかし、私が最後のコメントで述べたように、より多くの情報はちょうど ここ です!

__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
12
flow_chart

あなたが @Keith のような状況にいるなら、あなたは試すことができます:

print a.__dict__

それは私が良いスタイルと考えていることに反しますが、あなたがただデバッグしようとしているならそれはあなたが望むことをするべきです。

9
John

Python 3の場合:

特定のフォーマットが重要ではない場合(例えばデバッグのために)、以下のPrintableクラスから継承するだけです。すべてのオブジェクトにコードを書く必要はありません。

この からヒントを得た

class Printable:
    def __repr__(self):
        from pprint import pformat
        return "<" + type(self).__+ "> " + 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)
8
PeterM

@ 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__)))
7
MikeyB

このスレッドにはすでにたくさんの答えがありますが、それらのどれも特に私を助けてはくれませんでした。

クラスの最後に括弧があることを確認する必要があります。

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

注意してください、これは水素の終わりに括弧なしでは動作しません。彼らは必要です。

これが役立つことを願って、あなたがもう質問があるかどうか私に知らせてください。

1
Stumpy

クラス内で "__str__" 特殊メソッドを使用するだけです。例えば。

クラスAdiprogrammer:

def __init__(self, name):
    self.company_name = name

def __str__(self):
    return "I am the Founder of Adiprogrammer!"

yash = Adiprogrammer( "Aaditya")

プリント(ヤシ)

1
Yash Tile