1. Marat Khabibullin

    28.10.2010

    1 ↑
    0 ↓

    Как известно, при печати через pprint, unicode строки печатаются через спецсимволы, что очень неудобно. Например:

    >>> pprint.pprint({1: 'строка'})
    {1: '\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0'}
    
    >>> pprint.pprint({1: 'строка'.decode('utf8')})
    {1: u'\u0441\u0442\u0440\u043e\u043a\u0430'}
    

    Мне надоело с этим мерится, и я написал функцию, которая выводит объекты так же как pprint, но правильно отображает строки. Вот её код:

    import sys
    import pprint
    
    def pretty_print(object):
        class decoder_stream:
            def write(self, s):
                if s.startswith("'") and s.endswith("'"):
                    s = "'%s'" % s[1:-1].decode('string_escape')
                elif s.startswith("u'") and s.endswith("'"):
                    s = "u'%s'" % s[2:-1].decode('unicode_escape').encode('utf8')
                sys.stdout.write(s)
    
        pprint.pprint(object, decoder_stream())
    

    и пример использования:

    >>> pretty_print({1: 'строка'})
    {1: 'строка'}
    
    >>> pretty_print({1: 'строка'.decode('utf8')})
    {1: u'строка'}
    

    Принцип работы очень простой, в стандартную функцию pprint мы передаем наш decoder_stream, который преобразует все вхождения строк путем их декодирования.

    P.S. кому нужен полный интерфейс pprint`а могут добавить передачу аргументов

  2. Спасибо за идею.

    Хотя ваш пример и не вполне корректен.

    Я для себя написал это так:

    import sys
    from pprint import PrettyPrinter
    
    class MyPrettyPrinter(PrettyPrinter):
        def format(self, *args, **kwargs):
            repr, readable, recursive = PrettyPrinter.format(self, *args, **kwargs)
            if repr:
                if repr[0] in ('"', "'"):
                    repr = repr.decode('string_escape')
                elif repr[0:2] in ("u'", 'u"'):
                    repr = repr.decode('unicode_escape').encode(sys.stdout.encoding)
            return repr, readable, recursive
    
    def pprint(obj, stream=None, indent=1, width=80, depth=None):
        printer = MyPrettyPrinter(stream=stream, indent=indent, width=width, depth=depth)
        printer.pprint(obj)
    
    pprint({'здравствуй': u'мир'})
    pprint({'"здравствуй"': u'"мир"'})
    pprint({"'здравствуй'": u"'мир'"})
    
  3. Marat Khabibullin

    29.10.2010

    0 ↑
    0 ↓

    Спасибо, за усовершенствование!

    Действительно, ваш способ универсальнее и правильнее.

    Взял его на заметку

  4. shvechikov.com

    29.03.2015

    0 ↑
    0 ↓

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.