Как использовать pprint для печати объекта с помощью встроенного метода __str __ (self)?
У меня есть Python script, который обрабатывает .txt файл, содержащий информацию об использовании отчета. Я хотел бы найти способ чистой печати атрибутов объекта с использованием функции pprint pprint (vars (object)).
script читает файл и создает экземпляры класса Report. Здесь класс.
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)))
Я хотел бы иметь возможность печатать экземпляры Report cleanly 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
Когда я звоню
print record
для одного экземпляра отчета, это то, что я получаю в оболочке.
{'date_added': '1/3/2012 14:06',
'price': '0',
'report': 'some_report',
'retail_price': '0.25',
'user': 'some_username'}
None
Мой вопрос в два раза.
Во-первых, это хороший/желаемый способ для печати атрибутов объекта чисто? Есть ли лучший способ сделать это с помощью или без pprint?
Во-вторых, почему
None
печатать в оболочку в конце? Я смущен, когда это происходит.
Спасибо за любые советы.
Ответы
Ответ 1
pprint
- это еще одна форма печати. Когда вы говорите pprint(vars(self))
, он печатает vars в stdout и не возвращает ничего, потому что это функция void. Поэтому, когда вы передаете его в строку, он превращает None
(возвращается pprint
) в строку, которая затем печатается из первоначальной инструкции печати. Я предлагаю изменить печать на 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
Один вариант - использовать отформатированный вывод:
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()])
Надеюсь, что это помогло
Ответ 2
pprint.pprint
не возвращает строку; он фактически выполняет печать (по умолчанию для stdout, но вы можете указать выходной поток). Поэтому, когда вы пишете print record
, вызывается record.__str__()
, который вызывает pprint
, который возвращает None
. str(None)
- 'None'
, и он получает print
ed, поэтому вы видите None
.
Вместо этого вы должны использовать pprint.pformat
. (В качестве альтернативы вы можете передать экземпляр StringIO
в pprint
.)
Ответ 3
Решение Dan просто неверно, а Ismail - неполным.
-
__str__()
не вызывается, вызывается __repr__()
.
-
__repr__()
должен возвращать строку, как это делает pformat.
- обычно печатает отступы только 1 символ и пытается сохранить строки. Если вы пытаетесь выяснить структуру, установите ширину и высоту отступа.
Вот пример
class S:
def __repr__(self):
from pprint import pformat
return pformat(vars(self), indent=4, width=1)
a = S()
a.b = 'bee'
a.c = {'cats': ['blacky', 'tiger'], 'dogs': ['rex', 'king'] }
a.d = S()
a.d.more_c = a.c
print(a)
Отпечатает
{ 'b': 'bee',
'c': { 'cats': [ 'blacky',
'tiger'],
'dogs': [ 'rex',
'king']},
'd': { 'more_c': { 'cats': [ 'blacky',
'tiger'],
'dogs': [ 'rex',
'king']}}}
Что не является совершенным, но проходимым.
Ответ 4
Для довольно-печатных объектов, содержащих другие объекты, и т.д. pprint
недостаточно. Попробуйте IPython lib.pretty, который основан на модуле Ruby.
from IPython.lib.pretty import pprint
pprint(complex_object)
Ответ 5
Я думаю, beeprint - это то, что вам нужно.
Просто pip install beeprint
и измените свой код на:
def __str__(self):
from beeprint import pp
return pp(self, output=False)