python __str__ para un objeto

Mientras trataba de descubrir cómo funciona BeautifulSoup, aprendí el método __str__ (soy nuevo en Python). Entonces, si no percibí mal, entonces el método __str__ ayuda a determinar cómo se representará la clase si se imprime. Por ejemplo:

 class Foo: def __str__(self): return "bar" >>> x = Foo() >>> print x bar 

¿Derecha? Entonces, afirmando que tengo razón, ¿es posible anular el método __str__ de una lista de diccionarios? Quiero decir que en la clase Foo tienes:

 class Foo: def __init__(self): self.l = [{"Susan": ("Boyle", 50, "alive")}, {"Albert": ("Speer", 106, "dead")}] 

Ahora es posible tener el siguiente resultado?

 >>> x = Foo() >>> print xl "Susan Boyle is 50 and alive. Albert Speer is 106 and dead." 

EDITAR

Teniendo en cuenta la solución de AGF, ¿cómo puedo acceder al diccionario una vez más? Quiero decir que si defino el método __str__ entonces aparentemente debería definir otra cosa para recuperar el diccionario tal como está. Por favor considere el siguiente ejemplo:

 class PClass(dict): def __str__(self): # code to return the result that I want class Foo: def __init__(self): self.l = PClass({"Susan": ["Boyle", ........ }) >>> x = Foo() >>> print xl # result that works great >>> y = xl["Susan"] # this would not work. How can I achieve it? 

Necesitas subclasificar el artículo que estás imprimiendo.

 from itertools import chain class PrintableList(list): # for a list of dicts def __str__(self): return '. '.join(' '.join(str(x) for x in chain.from_iterable(zip((item[0], 'is', 'and'), item[1]))) for item in (item.items()[0] for item in self)) + '.' class PrintableDict(dict): # for a dict def __str__(self): return '. '.join(' '.join(str(x) for x in chain.from_iterable(zip((item[0], 'is', 'and'), item[1]))) for item in self.iteritems()) + '.' class Foo: def __init__(self): self.d = PrintableDict({"Susan": ("Boyle", 50, "alive"), "Albert": ("Speer", 106, "dead")}) class Bar: def __init__(self): self.l = PrintableList([{"Susan": ("Boyle", 50, "alive")}, {"Albert": ("Speer", 106, "dead")}]) foo = Foo() print self.d bar = Bar() print self.l 

Otra alternativa es anular __getattribute__ , que le permite personalizar cómo se devuelven los atributos:

 class Foo(object): def __init__(self): self.l = [{"Susan": ("Boyle", 50, "alive")}, {"Albert": ("Speer", 106, "dead")}] def __getattribute__(self, name): return PrintableList(l) attr = super(Foo, self).__getattribute__(name) items = sum([x.items() for x in attr], []) return ' '.join([' '.join([k, v[0], 'is', str(v[1]), 'and', v[2] + '.']) for k,v in items]) >>> f = Foo() >>> print fl <<< Susan Boyle is 50 and alive. Albert Speer is 106 and dead. 

Puedes definir __str__ para que tu clase de Foo devuelva lo que deseas:

 class Foo(): def __init__(self): self.l = [{"Susan": ("Boyle", 50, "alive")}, {"Albert": ("Speer", 106, " dead")}] def __str__(self): ret_str = "" for d in self.l: for k in d: ret_str += "".join([k, " ", d[k][0], " is ", str(d[k][1]), " and ", d[k][2], ". "]) return ret_str foo = Foo() print foo 

resultados en:

Susan Boyle tiene 50 años y está viva. Albert Speer tiene 106 años y está muerto.