Samstag, Januar 18, 2020

So drucken Sie Instanzen einer Klasse mit print()?

Ich bin erlernen der Seile in Python. Wenn ich versuche, drucken ein Objekt der Klasse Foobar mit der print() Funktion, bekomme ich eine Ausgabe wie diese:

<__main__.Foobar instance at 0x7ff2a18c>

Gibt es eine Möglichkeit, ich kann die Druck Verhalten (oder die string-Darstellung) eines Klasse und seine Objekte? Wenn ich zum Beispiel call print() auf ein class-Objekt, ich möchte zum ausgeben der Daten, die Mitglieder in einem bestimmten format. Wie das zu erreichen ist in Python?

Wenn Sie vertraut sind mit C++ – Klassen, die oben erreicht werden kann, für die standard – ostream durch hinzufügen einer friend ostream& operator << (ostream&, const Foobar&) – Methode für die Klasse.

10 Kommentare

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

    Den __str__ Methode ist, was passiert, wenn Sie es drucken, und die __repr__ Methode ist, was passiert, wenn Sie die repr() Funktion (oder, wenn man es mit der interaktive Eingabeaufforderung). Wenn dies nicht das Pythonic Methode, ich entschuldige mich, weil ich noch zu lernen – aber es funktioniert.

    Wenn keine __str__ Methode ist gegeben, Python druckt das Ergebnis __repr__ statt. Wenn Sie definieren __str__ aber nicht __repr__, Python verwenden, was Sie oben sehen, wie die __repr__, aber immer noch verwenden __str__ für den Druck.

    • es gibt auch eine unicode – Methode, die Sie verwenden können, anstelle von Str ; es ist zu beachten, dass sollte es wieder ein unicode-Objekt, kein string (wenn du aber einen string zurückgeben, der die Konvertierung in unicode wird man sowieso…)
    • Ich wusste nicht, über Sie, aber im Nachhinein macht es durchaus Sinn gegeben, Python-2.x ist gebrochen Unicode-handling.
    • Ich denke diese Antwort kann nicht abgeschlossen werden, ohne einen link zu hier!
    • Hat mich gerettet! Jedoch, nach re-implementieren Sie die Methode __repr__(self), print irreführen Benutzer. Sind Sie bewusst irgendwelche best practices?
    • Für Java-Programmierer: __str__(self) ist, wie die toString() der python-Welt
    • wie dieses aussieht ist nicht der Fall in Python ist3.6 mindestens zu dem was ich bin mit
    • wie dieses aussieht ist nicht der Fall in Python ist3.6 mindestens zu dem was ich bin mit
    • Was ist, wenn Sie nicht Bearbeiten können Sie die Klasse, die Sie wollen, um Informationen zu erhalten?.. wie etwas in einer shared library / plugin? Sicherlich muss es eine Art von generischen Klasse-Methode-Reflexion zur Verfügung, die nicht erfordern config?

  2. 120

    Als Chris Lutz erwähnt, dieses ist definiert durch die __repr__ Methode in Ihrer Klasse.

    Aus der Dokumentation der repr():

    Für viele Arten, diese Funktion macht einen Versuch, einen string zurückgeben, der würde die Ausbeute ein Objekt mit dem gleichen Wert zu übergeben eval(), da sonst die Darstellung ist ein string, eingeschlossen in Spitze Klammern enthält, der name und der Typ der das Objekt zusammen mit zusätzlichen Informationen oft auch den Namen und die Adresse des Objekts. Eine Klasse kann kontrollieren, was diese Funktion zurückgibt, die für seine Instanzen durch die Definition einer __repr__() Methode.

    Gegeben folgende Klasse 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)

    ..es handeln wird die folgende Art, in der Python-shell:

    >>> 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, wird print(t) (oder print(str(t))) wird das Ergebnis der __repr__ statt

    Wenn keine __repr__ Methode definiert ist, dann wird der Standardwert verwendet, das ist so ziemlich gleichwertig..

    def __repr__(self):
        return "<%s instance at %s>" % (self.__class__.__name__, id(self))
    • +1 aber Ihre Klasse code __str__ unterscheidet sich von der interaktiven shell die Ergebnisse, die Sie geben. 😛
    • Äh, Hoppla.. manuell ändern REPL Ausgabe endet nie gut. Ich sollte wohl doctest meine posts 😛
    • Danke. Aber, die string-Formatierung-Typ (%) in Ihrem Beispiel ist veraltet. Könnten Sie ändern, um die str.format() geben? 🙂
    • Die % string-Formatierung ist nicht veraltet, aus docs.python.org/whatsnew/2.6.html „der % – operator ist ergänzt durch eine leistungsfähige string-Formatierung Methode format()“
    • Dbr: Das ist wahr. Beachten Sie, dass die „What‘ s New In Python 3.0“ doc sagt auch, „format () – Methode […] Der plan ist, schließlich machen dies die einzige API für die string-Formatierung zu beginnen, abwertend der % – operator in Python 3.1.“
    • Schade, %’s schon sehr praktisch.
    • Das wird nicht funktionieren, wenn das Objekt in einer anderen Datenstruktur, versuchen: print([Test(123)])

  3. 44

    Einer generischen Art und Weise, die angewendet werden können, um jede Klasse ohne spezielle Formatierung getan werden könnte, wie folgt:

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

    Dann,

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

    produziert

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

    Nur meine zwei Cent hinzu zu @dbr Antwort, Folgendes ist ein Beispiel, wie die Umsetzung dieser Satz aus der offiziellen Dokumentation, die er zitiert:

    „[ … ], um einen string zurückgeben, der würde die Ausbeute ein Objekt mit dem gleichen Wert, wenn Sie übergeben, eval(), […]“

    Diese Klasse definition:

    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 leicht zu serialisieren Instanz Test Klasse:

    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

    So, läuft letzten Stück code, 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 ich schon in meinem letzten Kommentar: mehr info ist nur hier!

  5. 12

    Müssen Sie __repr__. Dies ist eine standard-Funktion 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
    • repr und str haben eine andere Semantik: repr werden sollte, Python-source, das (wieder-)erstellen, die die gleiche Objekt-das ist seine representation in code ; str sollte eine ziemlich userland stringification des Objekts.
  6. 12

    Wenn Sie in einer situation wie @Keith, die Sie könnten versuchen:

    print a.__dict__

    Geht es gegen das, was ich hielte guter Stil, aber wenn Sie nur versuchen zu Debuggen, dann sollte es das tun, was Sie wollen.

    • Würden Sie wissen, wie zu wissen, wenn die dict-key-Objekte in Ihren Werten?
    • Sind Sie Fragen, wie man rekursiv drucken Sie die Objekte als gut oder einfach nur bestimmen, wenn es Objekte?
  7. 8

    Für Python 3:

    Wenn das format nicht wichtig ist (z.B. für debugging) nur Erben von der Druckbare Klasse unten. Keine Notwendigkeit, code zu schreiben, für jedes Objekt.

    Inspiriert von diese Antwort

    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)
  8. 7

    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)

    Produziert optisch schöne Liste mit den Namen und Werten.

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

    Einen noch ausgefalleneren version (danke Ruud) sortiert die Elemente:

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

    Gibt es schon eine Menge Antworten in diesem thread, aber keiner von Ihnen besonders geholfen hat mir, musste ich es mir, so hoffe ich, dass dies ist ein wenig mehr informativ.

    Sie müssen nur sicherstellen, dass Sie Klammern am Ende der Klasse e.g:

    print(class())

    Hier ist ein Beispiel-code aus einem Projekt, an dem ich arbeitete:

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

    Drucken meine Wasserstoff-Klasse, ich habe folgende:

    print(Hydrogen())

    Bitte beachten Sie, dass dies nicht funktionieren wird, ohne die Klammern am Ende von Wasserstoff. Sind Sie notwendig.

    Hoffe, das hilft, lassen Sie mich wissen, wenn Sie haben mehr Fragen.

  10. 1

    verwenden Sie einfach „__str__“ spezielle Methode in Ihrer Klasse.
    Für die ex.

    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)

Kostenlose Online-Tests