2016-11-20 2 views
1

So habe ich die folgende Funktion:Wie füge ich eine Objektklasse an eine Liste an?

def find_by_name(self, name): 
    fitting_list = [p for p in self.__persons if name.lower() in p.name.lower()] 
    return fitting_list 

Und ich bekomme die folgende Ausgabe, wenn ich die Liste drucken möchten:

[<src.store.domain.person.Person object at 0x000001F88705B128>] 

Warum dies geschieht und wie kann ich es beheben?

+0

Was erwarten Sie stattdessen? –

+0

Ich erwarte, die Liste der Objekte in Bezug auf die if-Bedingung zu drucken. Ich habe __str__ Methode implementiert. Sollte das nicht genug sein? – Binary

+0

Das ist, was ist. Es druckt eine Liste mit einem Person-Objekt. Sie sehen die Standardmethode, mit der Python Objekte druckt. –

Antwort

1

list ist es egal, dass Ihre Klasse eine __str__ Methode hat.

Wenn Sie ein Objekt drucken, ruft print das Objekt str auf, um eine geeignete Zeichenfolge zu erhalten. Die Funktion str versucht, die __str__-Methode des Objekts aufzurufen. Wenn sie jedoch nicht hat, ruft sie stattdessen die Methode __repr__ des Objekts auf. Und wenn es keine Definition für __repr__ in der Klassendefinition dieses Objekts gibt, dann erhalten Sie die von der Elternklasse übernommene, typischerweise die __repr__ vom Basis object Typ.

list und die anderen integrierten Sammlungen wie tuple, set und dict haben keine __str__ Methode, so dass, wenn Sie versuchen, sie in Zeichenfolgen zu konvertieren (entweder explizit mit der str Funktion oder implizit über print) ihre __repr__ Methode wird aufgerufen. Und diese __repr__ Methoden rufen wiederum repr für jedes Element in der Sammlung. Wenn Sie also eines dieser Sammlungsobjekte an print übergeben, sehen Sie immer die __repr__ der Elemente. Und explizit str auf der Sammlung aufrufen wird keinen Unterschied machen.

Wenn Sie die __str__ Darstellung der Elemente in einer list oder Sammlung sehen möchten, müssen Sie über die Sammlung iterieren und str explizit auf jedem Element aufrufen.

Hier ist ein kleines Code-Snippet (geeignet für Python 2 & 3), die diese Punkte veranschaulicht.

from __future__ import print_function 

class Test(object): 
    def __str__(self): 
     return 'Test str' 
    def __repr__(self): 
     return 'Test repr' 

a = [Test(), Test()] 
print(id(a.__repr__), id(a.__str__)) 
print(a, str(a), repr(a)) 

for u in a: 
    print(u, str(u), repr(u)) 

Ausgang

3075508812 3075508812 
[Test repr, Test repr] [Test repr, Test repr] [Test repr, Test repr] 
Test str Test str Test repr 
Test str Test str Test repr 

Also, wenn Sie in der Lage sein wollen, eine Liste Ihrer Objekte als eine Einheit und die Saiten menschenfreundlich sein Objekt haben zu drucken, haben Sie ein paar Auswahl:

  1. ändern Sie den Namen Ihres __str__ Methode __repr__. Dies ist der einfachste Weg, und wie ich bereits sagte, wird die __repr__ verwendet, wenn eine __str__ nicht gefunden werden kann, wenn das Objekt an str übergeben wird.

  2. Lassen Sie die vorhandene __str__-Methode in Ruhe und erstellen Sie eine __repr__, die humanfreundlicher ist.Es wird jedoch vorgeschlagen, dass die __repr__ nützliche Informationen für einen Programmierer anzeigen, der sie sieht, und wenn es praktisch ist, ist es nett, wenn die __repr__ Zeichenfolge kopiert werden kann & in den Interpreter oder Skript eingefügt, um das Objekt neu zu erstellen.

  3. Lassen Sie die vorhandene __str__-Methode in Ruhe und erstellen Sie eine __repr__, die __str__ aufruft. Obwohl es gültig ist, ist das ein bisschen albern. Eine verwandte Strategie besteht darin, __repr__ als Klassenattribut festzulegen, das auf __str__ verweist. Siehe unten für ein Beispiel.

class Test(object): 
    def __str__(self): 
     return 'Test str' 
    __repr__ = __str__ 
+0

Vielen Dank. Das hat mich dazu gebracht, das __str__-Verfahren viel besser zu verstehen als jedes andere Tutorial, das ich gefunden habe. – Binary

3

Dies ist nur die __repr__ des Objekts. Die __repr__ soll eine maschinenlesbare Darstellung des Objekts sein und Sie können es ändern, indem Sie es übersteuern.

Verwandte Themen