¿Cómo usar pprint para imprimir un objeto usando el método __str __ (self) incorporado?

Tengo una secuencia de comandos de Python que procesa un archivo .txt que contiene información sobre el uso del informe. Me gustaría encontrar una manera de imprimir de forma limpia los atributos de un objeto utilizando la función pprint (vars (objeto)) de pprint.

El script lee el archivo y crea instancias de una clase de Informe. Aquí está la clase.

class Report(object): def __init__(self, line, headers): self.date_added=get_column_by_header(line,headers,"Date Added") self.user=get_column_by_header(line,headers,"Login ID") self.report=get_column_by_header(line,headers,"Search/Report Description") self.price=get_column_by_header(line,headers,"Price") self.retail_price=get_column_by_header(line,headers,"Retail Price") def __str__(self): from pprint import pprint return str(pprint(vars(self))) 

Me gustaría poder imprimir instancias de Report limpiamente a-la-pprint.

 for i,line in enumerate(open(path+file_1,'r')): line=line.strip().split("|") if i==0: headers=line if i==1: record=Report(line,headers) print record 

Cuando llamo

 print record 

para una sola instancia de Informe, esto es lo que obtengo en el shell.

 {'date_added': '1/3/2012 14:06', 'price': '0', 'report': 'some_report', 'retail_price': '0.25', 'user': 'some_username'} None 

Mi pregunta es doble.

Primero, ¿es esta una forma buena / deseada de imprimir los atributos de un objeto de manera limpia? ¿Hay una mejor manera de hacer esto con o sin pprint?

Segundo, porque hace

 None 

Imprimir en la shell al final? Estoy confundido de donde viene eso.

Gracias por cualquier consejo.

pprint es sólo otra forma de impresión. Cuando dices pprint(vars(self)) imprime vars en stdout y no devuelve ninguno porque es una función nula. Por lo tanto, cuando lo convierte en una cadena, convierte None (devuelto por pprint ) en una cadena que luego se imprime desde la statement de impresión inicial. Yo sugeriría cambiar su impresión para pprint o redefinir impresión como impresión si es todo lo que pprint .

 def __str__(self): from pprint import pprint return str(vars(self)) for i,line in enumerate(open(path+file_1,'r')): line = line.strip().split("|") if i == 0: headers = line if i == 1: record = Report(line,headers) pprint record 

Una alternativa es usar una salida formateada:

 def __str__(self): return "date added: %s\nPrice: %s\nReport: %s\nretail price: %s\nuser: %s" % tuple([str(i) for i in vars(self).values()]) 

Espero que esto haya ayudado

La solución de Dan está mal, e Ismail está incompleta.

  1. __str__() no se llama, __repr__() se llama.
  2. __repr__() debería devolver una cadena, como lo hace pformat.
  3. normalmente imprime solo sangra 1 carácter e intenta guardar líneas. Si está tratando de averiguar la estructura, establezca el ancho bajo y la sangría alta.

Aquí hay un ejemplo

 class S: def __repr__(self): from pprint import pformat return pformat(vars(self), indent=4, width=1) a = S() ab = 'bee' ac = {'cats': ['blacky', 'tiger'], 'dogs': ['rex', 'king'] } ad = S() admore_c = ac print(a) 

Esto imprime

 { 'b': 'bee', 'c': { 'cats': [ 'blacky', 'tiger'], 'dogs': [ 'rex', 'king']}, 'd': { 'more_c': { 'cats': [ 'blacky', 'tiger'], 'dogs': [ 'rex', 'king']}}} 

Lo cual no es perfecto, sino pasable.

pprint.pprint no devuelve una cadena; en realidad realiza la impresión (de forma predeterminada a la salida estándar, pero puede especificar una secuencia de salida). Así que cuando escribe print record , se llama al record.__str__() , que llama a pprint , que devuelve None . str(None) es 'None' , y eso se print , por lo que no ve None .

Deberías usar pprint.pformat en pprint.pformat lugar. (Alternativamente, puede pasar una instancia de pprint para pprint ).

Para los objetos de impresión bonita que contienen otros objetos, etc. la pprint no es suficiente. Intente lib.pretty de IPython , que se basa en un módulo Ruby.

 from IPython.lib.pretty import pprint pprint(complex_object) 

Creo que beeprint es lo que necesitas.

Simplemente pip install beeprint y cambie su código a:

 def __str__(self): from beeprint import pp return pp(self, output=False)