"pprint" --- Impressão Bonita de Dados
**************************************

**Código-fonte:** Lib/pprint.py

======================================================================

O módulo "pprint" fornece a capacidade de "imprimir de forma bonita"
estruturas de dados Python arbitrárias em um formato que pode ser
usado como entrada para o interpretador. Se as estruturas formatadas
incluírem objetos que não sejam tipos fundamentais do Python, a
representação poderá não ser carregável. Este pode ser o caso se
objetos como arquivos, soquetes ou classes forem incluídos, bem como
muitos outros objetos que não são representáveis como literais do
Python.

A representação formatada mantém os objetos em uma única linha, se
possível, e os divide em várias linhas se não couberem na largura
permitida. Construa objetos "PrettyPrinter" explicitamente se precisar
ajustar a restrição de largura.

Os dicionários são classificados por chave antes que a exibição seja
calculada.

Alterado na versão 3.9: Adicionado suporte para impressão bonita de
"types.SimpleNamespace".

Alterado na versão 3.10: Adicionado suporte para impressão bonita de
"dataclasses.dataclass".


Funções
=======

pprint.pp(object, *args, sort_dicts=False, **kwargs)

   Imprime a representação formatada de *object* seguida por uma nova
   linha. Se *sort_dicts* for falso (o padrão), os dicionários serão
   exibidos com suas chaves na ordem de inserção, caso contrário, as
   chaves do dict serão classificadas. *args* e *kwargs* serão
   passados para "pprint()" como parâmetros de formatação.

   >>> import pprint
   >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
   >>> stuff.insert(0, stuff)
   >>> pprint.pp(stuff)
   [<Recursion on list with id=...>,
    'spam',
    'eggs',
    'lumberjack',
    'knights',
    'ni']

   Novo na versão 3.8.

pprint.pprint(object, stream=None, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True, underscore_numbers=False)

   Imprime a representação formatada de *object* em *stream*, seguida
   por uma nova linha. Se *stream* for "None", "sys.stdout" será
   usado. Isto pode ser usado no interpretador interativo em vez da
   função "print()" para inspecionar valores (você pode até reatribuir
   "print = pprint.pprint" para uso dentro de um escopo).

   Os parâmetros de configuração *stream*, *indent*, *width*,
   *profundidade*, *compact*, *sort_dicts* e *underscore_numbers* são
   passados para o construtor do "PrettyPrinter" e seus significados
   são descritos em sua documentação abaixo.

   Observe que *sort_dicts* é "True" por padrão e você pode querer
   usar "pp()" em vez disso, onde é "False" por padrão.

pprint.pformat(object, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True, underscore_numbers=False)

   Retorna a representação formatada de *object* como uma string.
   *indent*, *width*, *depth*, *compact*, *sort_dicts* e
   *underscore_numbers* são passados para o construtor de
   "PrettyPrinter" como parâmetros de formatação e seus significados
   são descritos em sua documentação abaixo.

pprint.isreadable(object)

   Determina se a representação formatada de *object* é "legível" ou
   pode ser usada para reconstruir o valor usando "eval()". Isso
   sempre retorna "False" para objetos recursivos.

   >>> pprint.isreadable(stuff)
   False

pprint.isrecursive(object)

   Determine if *object* requires a recursive representation.

pprint.saferepr(object)

   Return a string representation of *object*, protected against
   recursive data structures.  If the representation of *object*
   exposes a recursive entry, the recursive reference will be
   represented as "<Recursion on typename with id=number>".  The
   representation is not otherwise formatted.

   >>> pprint.saferepr(stuff)
   "[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']"


Objetos PrettyPrinter
=====================

Este módulo define uma classe:

class pprint.PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, compact=False, sort_dicts=True, underscore_numbers=False)

   Constrói uma instância "PrettyPrinter". Este construtor aceita
   vários parâmetros nomeados.

   *stream* (padrão "sys.stdout") é um *objeto arquivo ou similar* no
   qual a saída será escrita chamando seu método "write()". Se
   *stream* e "sys.stdout" forem "None", então "pprint()" retornará
   silenciosamente.

   Outros valores configuram a maneira como o aninhamento de
   estruturas de dados complexas é exibido.

   *indent* (padrão 1) especifica a quantidade de indentação
   adicionado para cada nível de aninhamento.

   *depth* controla o número de níveis de aninhamento que podem ser
   impressos; se a estrutura de dados que está sendo impressa for
   muito profunda, o próximo nível contido será substituído por "...".
   Por padrão, não há restrição na profundidade dos objetos que estão
   sendo formatados.

   *width* (padrão 80) especifica o número máximo desejado de
   caracteres por linha na saída. Se uma estrutura não puder ser
   formatada dentro da restrição de largura, será feito o melhor
   esforço.

   *compact* afeta a forma como sequências longas (listas, tuplas,
   conjuntos, etc.) são formatadas. Se *compact* for falso (o padrão),
   então cada item de uma sequência será formatado em uma linha
   separada. Se *compact* for verdadeiro, tantos itens quantos
   couberem na *width* serão formatados em cada linha de saída.

   Se *sort_dicts* for verdadeiro (o padrão), os dicionários serão
   formatados com suas chaves classificadas, caso contrário, serão
   exibidos na ordem de inserção.

   Se *underscore_numbers* for verdadeiro, os números inteiros serão
   formatados com o caractere "_" para um separador de milhares, caso
   contrário, os sublinhados não serão exibidos (o padrão).

   Alterado na versão 3.4: Adicionado o parâmetro *compact*.

   Alterado na versão 3.8: Adicionado o parâmetro *sort_dicts*.

   Alterado na versão 3.10: Adicionado o parâmetro
   *underscore_numbers*.

   Alterado na versão 3.11: Não tenta mais escrever em "sys.stdout" se
   for "None".

   >>> import pprint
   >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
   >>> stuff.insert(0, stuff[:])
   >>> pp = pprint.PrettyPrinter(indent=4)
   >>> pp.pprint(stuff)
   [   ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
       'spam',
       'eggs',
       'lumberjack',
       'knights',
       'ni']
   >>> pp = pprint.PrettyPrinter(width=41, compact=True)
   >>> pp.pprint(stuff)
   [['spam', 'eggs', 'lumberjack',
     'knights', 'ni'],
    'spam', 'eggs', 'lumberjack', 'knights',
    'ni']
   >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
   ... ('parrot', ('fresh fruit',))))))))
   >>> pp = pprint.PrettyPrinter(depth=6)
   >>> pp.pprint(tup)
   ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))

Instâncias "PrettyPrinter" contêm os seguintes métodos:

PrettyPrinter.pformat(object)

   Retorna a representação formatada de *object*. Isso leva em
   consideração as opções passadas para o construtor "PrettyPrinter".

PrettyPrinter.pprint(object)

   Exibe a representação formatada de *object* no fluxo configurado,
   seguida por uma nova linha.

Os métodos a seguir fornecem as implementações para as funções
correspondentes com os mesmos nomes. Usar esses métodos em uma
instância é um pouco mais eficiente já que novos objetos
"PrettyPrinter" não precisam ser criados.

PrettyPrinter.isreadable(object)

   Determina se a representação formatada do objeto é "legível" ou
   pode ser usada para reconstruir o valor usando "eval()". Observe
   que isso retorna "False" para objetos recursivos. Se o parâmetro
   *depth* de "PrettyPrinter" estiver definido e o objeto for mais
   profundo que o permitido, isso retornará "False".

PrettyPrinter.isrecursive(object)

   Determina se o objeto requer uma representação recursiva.

Este método é fornecido como um gancho para permitir que as subclasses
modifiquem a maneira como os objetos são convertidos em strings.  A
implementação padrão usa os componentes internos da implementação de
"saferepr()".

PrettyPrinter.format(object, context, maxlevels, level)

   Retorna três valores: a versão formatada de *object* como uma
   string, um sinalizador indicando se o resultado é legível e um
   sinalizador indicando se a recursão foi detectada.  O primeiro
   argumento é o objeto a ser apresentado.  O segundo é um dicionário
   que contém o "id()" de objetos que fazem parte do contexto de
   apresentação atual (contêineres diretos e indiretos para *objects*
   que estão afetando a apresentação) como chaves; se for necessário
   apresentar um objeto que já esteja representado em *context*, o
   terceiro valor de retorno deverá ser "True".  Chamadas recursivas
   ao método "format()" devem adicionar entradas adicionais para
   contêineres neste dicionário.  O terceiro argumento, *maxlevels*,
   fornece o limite solicitado para recursão;  será "0" se não houver
   limite solicitado.  Este argumento deve ser passado sem
   modificações para chamadas recursivas. O quarto argumento, *level*,
   fornece o nível atual; chamadas recursivas devem receber um valor
   menor que o da chamada atual.


Exemplo
=======

Para demonstrar vários usos da função "pp()" e seus parâmetros, vamos
buscar informações sobre um projeto no PyPI:

   >>> import json
   >>> import pprint
   >>> from urllib.request import urlopen
   >>> with urlopen('https://pypi.org/pypi/sampleproject/json') as resp:
   ...     project_info = json.load(resp)['info']

Em sua forma básica, "pp()" mostra o objeto inteiro:

   >>> pprint.pp(project_info)
   {'author': 'The Python Packaging Authority',
    'author_email': 'pypa-dev@googlegroups.com',
    'bugtrack_url': None,
    'classifiers': ['Development Status :: 3 - Alpha',
                    'Intended Audience :: Developers',
                    'License :: OSI Approved :: MIT License',
                    'Programming Language :: Python :: 2',
                    'Programming Language :: Python :: 2.6',
                    'Programming Language :: Python :: 2.7',
                    'Programming Language :: Python :: 3',
                    'Programming Language :: Python :: 3.2',
                    'Programming Language :: Python :: 3.3',
                    'Programming Language :: Python :: 3.4',
                    'Topic :: Software Development :: Build Tools'],
    'description': 'A sample Python project\n'
                   '=======================\n'
                   '\n'
                   'This is the description file for the project.\n'
                   '\n'
                   'The file should use UTF-8 encoding and be written using '
                   'ReStructured Text. It\n'
                   'will be used to generate the project webpage on PyPI, and '
                   'should be written for\n'
                   'that purpose.\n'
                   '\n'
                   'Typical contents for this file would include an overview of '
                   'the project, basic\n'
                   'usage examples, etc. Generally, including the project '
                   'changelog in here is not\n'
                   'a good idea, although a simple "What\'s New" section for the '
                   'most recent version\n'
                   'may be appropriate.',
    'description_content_type': None,
    'docs_url': None,
    'download_url': 'UNKNOWN',
    'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
    'home_page': 'https://github.com/pypa/sampleproject',
    'keywords': 'sample setuptools development',
    'license': 'MIT',
    'maintainer': None,
    'maintainer_email': None,
    'name': 'sampleproject',
    'package_url': 'https://pypi.org/project/sampleproject/',
    'platform': 'UNKNOWN',
    'project_url': 'https://pypi.org/project/sampleproject/',
    'project_urls': {'Download': 'UNKNOWN',
                     'Homepage': 'https://github.com/pypa/sampleproject'},
    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
    'requires_dist': None,
    'requires_python': None,
    'summary': 'A sample Python project',
    'version': '1.2.0'}

O resultado pode ser limitado a uma certa *depth* (reticências são
usadas para conteúdos mais profundos):

   >>> pprint.pp(project_info, depth=1)
   {'author': 'The Python Packaging Authority',
    'author_email': 'pypa-dev@googlegroups.com',
    'bugtrack_url': None,
    'classifiers': [...],
    'description': 'A sample Python project\n'
                   '=======================\n'
                   '\n'
                   'This is the description file for the project.\n'
                   '\n'
                   'The file should use UTF-8 encoding and be written using '
                   'ReStructured Text. It\n'
                   'will be used to generate the project webpage on PyPI, and '
                   'should be written for\n'
                   'that purpose.\n'
                   '\n'
                   'Typical contents for this file would include an overview of '
                   'the project, basic\n'
                   'usage examples, etc. Generally, including the project '
                   'changelog in here is not\n'
                   'a good idea, although a simple "What\'s New" section for the '
                   'most recent version\n'
                   'may be appropriate.',
    'description_content_type': None,
    'docs_url': None,
    'download_url': 'UNKNOWN',
    'downloads': {...},
    'home_page': 'https://github.com/pypa/sampleproject',
    'keywords': 'sample setuptools development',
    'license': 'MIT',
    'maintainer': None,
    'maintainer_email': None,
    'name': 'sampleproject',
    'package_url': 'https://pypi.org/project/sampleproject/',
    'platform': 'UNKNOWN',
    'project_url': 'https://pypi.org/project/sampleproject/',
    'project_urls': {...},
    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
    'requires_dist': None,
    'requires_python': None,
    'summary': 'A sample Python project',
    'version': '1.2.0'}

Além disso, a largura *width* máxima do caractere pode ser sugerida.
Se um objeto longo não puder ser dividido, a largura especificada será
excedida:

   >>> pprint.pp(project_info, depth=1, width=60)
   {'author': 'The Python Packaging Authority',
    'author_email': 'pypa-dev@googlegroups.com',
    'bugtrack_url': None,
    'classifiers': [...],
    'description': 'A sample Python project\n'
                   '=======================\n'
                   '\n'
                   'This is the description file for the '
                   'project.\n'
                   '\n'
                   'The file should use UTF-8 encoding and be '
                   'written using ReStructured Text. It\n'
                   'will be used to generate the project '
                   'webpage on PyPI, and should be written '
                   'for\n'
                   'that purpose.\n'
                   '\n'
                   'Typical contents for this file would '
                   'include an overview of the project, '
                   'basic\n'
                   'usage examples, etc. Generally, including '
                   'the project changelog in here is not\n'
                   'a good idea, although a simple "What\'s '
                   'New" section for the most recent version\n'
                   'may be appropriate.',
    'description_content_type': None,
    'docs_url': None,
    'download_url': 'UNKNOWN',
    'downloads': {...},
    'home_page': 'https://github.com/pypa/sampleproject',
    'keywords': 'sample setuptools development',
    'license': 'MIT',
    'maintainer': None,
    'maintainer_email': None,
    'name': 'sampleproject',
    'package_url': 'https://pypi.org/project/sampleproject/',
    'platform': 'UNKNOWN',
    'project_url': 'https://pypi.org/project/sampleproject/',
    'project_urls': {...},
    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
    'requires_dist': None,
    'requires_python': None,
    'summary': 'A sample Python project',
    'version': '1.2.0'}
