Как использовать 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)