it-swarm.com.de

Wie drucke ich Instanzen einer Klasse mit print ()?

Ich lerne die Seile in Python. Wenn ich versuche, ein Objekt der Klasse Foobar mit der Funktion print() zu drucken, erhalte ich eine Ausgabe wie die folgende:

<__main__.Foobar instance at 0x7ff2a18c>

Gibt es eine Möglichkeit, wie ich das Druckverhalten (oder die Zeichenfolgendarstellung einstellen kann? )) einer Klasse und ihrer Objekte ? Wenn ich zum Beispiel print() für ein Klassenobjekt aufrufe, möchte ich seine Datenelemente in einem bestimmten Format drucken. Wie erreicht man das in Python?

Wenn Sie mit C++ - Klassen vertraut sind, können Sie die obigen Schritte für die Standardmethode ostream ausführen, indem Sie eine friend ostream& operator << (ostream&, const Foobar&) -Methode für die Klasse hinzufügen.

459
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

Die __str__ -Methode passiert, wenn Sie es drucken, und die __repr__ -Methode passiert, wenn Sie die repr() -Funktion verwenden (oder wenn Sie sie mit der interaktiven Eingabeaufforderung betrachten) ). Wenn dies nicht die gängigste pythonische Methode ist, entschuldige ich mich, weil ich auch noch lerne - aber es funktioniert.

Wenn keine __str__ -Methode angegeben ist, gibt Python stattdessen das Ergebnis von __repr__ aus. Wenn Sie __str__, aber nicht __repr__ definieren, verwendet Python das, was Sie oben als __repr__ sehen, aber immer noch __str__ zum Drucken.

539
Chris Lutz

Wie Chris Lutz erwähnt hat , dies wird durch die __repr__ -Methode in Ihrer Klasse definiert.

Aus der Dokumentation von repr() :

Bei vielen Typen wird mit dieser Funktion versucht, eine Zeichenfolge zurückzugeben, die bei Übergabe an eval() ein Objekt mit demselben Wert ergibt. Andernfalls ist die Darstellung eine Zeichenfolge in spitzen Klammern, die den Namen des Objekttyps sowie weitere Informationen enthält Informationen oft einschließlich des Namens und der Adresse des Objekts. Eine Klasse kann steuern, was diese Funktion für ihre Instanzen zurückgibt, indem sie eine Methode __repr__() definiert.

Bei folgendem Klassentest:

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)

..es wird folgendermaßen in der Python Shell verfahren:

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

Wenn keine __str__ -Methode definiert ist, verwendet print(t) (oder print(str(t))) stattdessen das Ergebnis von __repr__

Wenn keine __repr__ -Methode definiert ist, wird die Standardmethode verwendet.

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

Eine generische Methode, die auf jede Klasse ohne bestimmte Formatierung angewendet werden kann, könnte folgendermaßen aussehen:

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

Und dann,

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

produziert

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

Wenn Sie sich in einer Situation wie @ Keith befinden, können Sie Folgendes versuchen:

print a.__dict__

Es widerspricht dem, was ich für einen guten Stil halte, aber wenn Sie nur versuchen zu debuggen, sollte es tun, was Sie wollen.

13
John

Um meine zwei Cent zu @ dbrs Antwort hinzuzufügen, folgt ein Beispiel für die Implementierung dieses Satzes aus der offiziellen Dokumentation, die er zitiert hat:

"[...] um einen String zurückzugeben, der ein Objekt mit demselben Wert ergibt, wenn er an eval () übergeben wird, [...]"

In Anbetracht dieser Klassendefinition:

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)

Nun ist es einfach, die Instanz der Klasse Test zu serialisieren:

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

Wenn wir also den letzten Code ausführen, erhalten wir:

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

Aber wie gesagt in meinem letzten Kommentar: Mehr Infos gibt es nur hier !

Sie müssen __repr__ verwenden. Dies ist eine Standardfunktion wie __init__. Zum Beispiel:

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

Für Python 3:

Wenn das spezifische Format nicht wichtig ist (z. B. zum Debuggen), erben Sie es einfach von der unten angegebenen Printable-Klasse. Es muss kein Code für jedes Objekt geschrieben werden.

Inspiriert von this answer

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

Eine schönere Version der Antwort von @ 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)

Erzeugt eine visuell ansprechende Liste der Namen und Werte.

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

Eine noch schickere Version (danke Ruud) sortiert die Artikel:

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

Es gibt bereits viele Antworten in diesem Thread, aber keine hat mir besonders geholfen. Ich musste es selbst ausarbeiten, also hoffe ich, dass diese etwas informativer ist.

Sie müssen nur sicherstellen, dass Sie am Ende Ihrer Klasse Klammern haben, z. B .:

print(class())

Hier ist ein Beispiel für Code aus einem Projekt, an dem ich gearbeitet habe:

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

Um meine Wasserstoffklasse auszudrucken, habe ich Folgendes verwendet:

print(Hydrogen())

Bitte beachten Sie, dass dies ohne die Klammern am Ende von Wasserstoff nicht funktioniert. Sie sind notwendig.

Hoffe das hilft, lass es mich wissen, wenn du weitere Fragen hast.

1
Stumpy

verwenden Sie einfach die spezielle Methode "__ str __" in Ihrer Klasse. Zum Beispiel.

klasse Adiprogrammer:

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

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

yash = Adiprogrammer ("Aaditya")

print (yash)

1
Yash Tile