Como eu olho dentro de um objeto Python?


291

Estou começando a codificar em vários projetos usando Python (incluindo desenvolvimento web Django e desenvolvimento de jogos Panda3D).

Para me ajudar a entender o que está acontecendo, gostaria basicamente de 'olhar' dentro dos objetos Python para ver como eles funcionam - como seus métodos e propriedades.

Então, digamos que eu tenho um objeto Python, o que eu precisaria para imprimir seu conteúdo? É mesmo possível?

Respostas:


352

Python tem um forte conjunto de recursos de introspecção.

Dê uma olhada nas seguintes funções internas :

type()e dir()são particularmente úteis para inspecionar o tipo de um objeto e seu conjunto de atributos, respectivamente.


25
Não sabia que o termo era "introspecção". Isso é uma grande ajuda! Além de todas as funções que você me deu ... Obrigado!
22630 LittleJim84

2
property, classmethod e staticmethod não estão relacionados à introspecção. Todos esses métodos criam tipos especiais de objetos que podem ser usados ​​para definir classes com comportamento especial, mas não ajudam em inspecionar essas classes ou construções.
SingleNegationElimination

A resposta do @Brian abaixo mostra como também visualizar o código fonte de vários objetos python de dentro do python. Era isso que eu estava procurando originalmente e tenho certeza de que não ficarei sozinho. (Pode valer a pena incluindo uma referência à sua resposta nesta resposta, já que é a mais aceita.)
michaelavila

É como o "IntelliSense" embutido para python. Eu amo isso.
de Bruno Bieri

7
Eu acho que é uma resposta ruim. em vez de nos dar uma solução, apenas nos fornece tudo relacionado a isso na documentação
Ishan Srivastava

176

object.__dict__


12
vars(object)é feito para isso.
liberforce

6
Na verdade, from pprint import pprint; pprint(vars(object))me deu uma visão muito boa do conteúdo do meu objeto. Obrigado @liberforce
N. Maks

a melhor maneira de ver objeto e seu conteúdo em uma string
Peter Krauss

Esta é uma ótima maneira de ver objetos que implementam os métodos de representação, ou objetos como googleapiclient.errors.HttpError que quando você imprimi-los eles imprimem informações insuficientes, com certeza, graças @ mtasic85
Felipe Valdes

65

Primeiro, leia a fonte.

Segundo, use a dir()função


92
Eu reverteria essa ordem.
Bayer

5
A fonte é mais informativa que dir () e um hábito melhor a ser desenvolvido.
214/09 S.Lott

14
Eu peço desculpa mas não concordo. dir () é muito mais rápido e, em 99% dos casos, vamos descobrir o que você precisa em combinação com a ajuda ().
Bayer

7
Eu concordo com geralmente inútil. Muitas vezes, basta uma simples chamada para dir (), poupando assim o trabalho de procurar o código-fonte.
Sasha Chedygov 18/06/09

3
Às vezes, a inspeção de objetos em tempo de execução pode ser útil, mas a leitura de fontes não. Por exemplo, classes activationplib.py e seus métodos :).
Denis Barmenkov

61

Estou surpreso que ninguém tenha mencionado a ajuda ainda!

In [1]: def foo():
   ...:     "foo!"
   ...:

In [2]: help(foo)
Help on function foo in module __main__:

foo()
    foo!

A Ajuda permite que você leia a documentação e tenha uma idéia de quais atributos uma classe pode ter, o que é bastante útil.


Então você usa as outras técnicas mencionadas aqui. Mas se a documentação estiver disponível, considere-a canônica.
Edward Falk

Não tenho certeza se o python atualizou essa função nos últimos anos, mas "help (object_name)" fornece uma visão geral completa em um formato altamente estruturado. É um guardião. Obrigado.
Brian Cugelman

27

Se for para exploração para ver o que está acontecendo, eu recomendo olhar para o IPython . Isso adiciona vários atalhos para obter a documentação, as propriedades e até o código fonte dos objetos. Por exemplo, anexando um "?" para uma função fornecerá a ajuda para o objeto (efetivamente um atalho para "help (obj)", enquanto o uso de dois? 's (" func??") exibirá o código fonte, se estiver disponível.

Também existem muitas conveniências adicionais, como preenchimento de guias, impressão bonita de resultados, histórico de resultados etc. que o tornam muito útil para esse tipo de programação exploratória.

Para uso mais programático de introspecção, os builtins básicos como dir(), vars(), getattretc vai ser útil, mas é bem vale o seu tempo para verificar a inspecionar módulo. Para buscar a fonte de uma função, use " inspect.getsource" por exemplo, aplicando-a a si mesma:

>>> print inspect.getsource(inspect.getsource)
def getsource(object):
    """Return the text of the source code for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a single string.  An
    IOError is raised if the source code cannot be retrieved."""
    lines, lnum = getsourcelines(object)
    return string.join(lines, '')

inspect.getargspec também é frequentemente útil se você estiver lidando com a quebra ou manipulação de funções, pois fornecerá os nomes e os valores padrão dos parâmetros de função.


18

Se você estiver interessado em uma GUI para isso, dê uma olhada no objbrowser . Ele usa o módulo de inspeção da biblioteca padrão do Python para a introspecção de objetos abaixo.

objbrowserscreenshot


9

Você pode listar os atributos de um objeto com dir () no shell:

>>> dir(object())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

Obviamente, também existe o módulo de inspeção: http://docs.python.org/library/inspect.html#module-inspect


8
"""Visit http://diveintopython.net/"""

__author__ = "Mark Pilgrim (mark@diveintopython.org)"


def info(object, spacing=10, collapse=1):
    """Print methods and doc strings.

    Takes module, class, list, dictionary, or string."""
    methodList = [e for e in dir(object) if callable(getattr(object, e))]
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
    print "\n".join(["%s %s" %
                     (method.ljust(spacing),
                      processFunc(str(getattr(object, method).__doc__)))
                     for method in methodList])

if __name__ == "__main__":
    print help.__doc__

4
Isso funciona bem no python 3 se você apenas adicionar parênteses nas impressões.
ConstantineK

8

Tente ppretty

from ppretty import ppretty


class A(object):
    s = 5

    def __init__(self):
        self._p = 8

    @property
    def foo(self):
        return range(10)


print ppretty(A(), indent='    ', depth=2, width=30, seq_length=6,
              show_protected=True, show_private=False, show_static=True,
              show_properties=True, show_address=True)

Resultado:

__main__.A at 0x1debd68L (
    _p = 8, 
    foo = [0, 1, 2, ..., 7, 8, 9], 
    s = 5
)

7

Outros já mencionaram o dir () interno que soa como o que você está procurando, mas aqui está outra boa dica. Muitas bibliotecas - incluindo a maioria da biblioteca padrão - são distribuídas na forma de origem. Ou seja, você pode facilmente ler o código-fonte diretamente. O truque está em encontrá-lo; por exemplo:

>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'

O arquivo * .pyc é compilado, então remova o 'c' à direita e abra o arquivo * .py não compilado no seu editor ou visualizador de arquivos favorito:

/usr/lib/python2.5/string.py

Achei isso incrivelmente útil para descobrir coisas como quais exceções são geradas a partir de uma determinada API. Esse tipo de detalhe raramente é bem documentado no mundo Python.


7

Embora pprintjá tenha sido mencionado por outras pessoas, eu gostaria de adicionar algum contexto.

O módulo pprint fornece a capacidade de “imprimir de maneira bonita” as estruturas de dados Python arbitrárias em um formulário que pode ser usado como entrada para o intérprete. Se as estruturas formatadas incluem objetos que não são tipos fundamentais de Python, a representação pode não ser carregável. Esse pode ser o caso se objetos como arquivos, soquetes, classes ou instâncias forem incluídos, bem como muitos outros objetos internos que não são representáveis ​​como constantes do Python.

pprint pode estar em alta demanda por desenvolvedores com experiência em PHP que procuram uma alternativa para var_dump() .

Objetos com um atributo dict podem ser despejados muito bem usando o método pprint()mixed with vars(), que retorna o __dict__atributo para um módulo, classe, instância, etc .:

from pprint import pprint
pprint(vars(your_object))

Portanto, não há necessidade de um loop .

Para despejar todas as variáveis ​​contidas no escopo global ou local, basta usar:

pprint(globals())
pprint(locals())

locals()mostra variáveis ​​definidas em uma função.
Também é útil acessar funções com o nome correspondente como uma chave de cadeia, entre outros usos :

locals()['foo']() # foo()
globals()['foo']() # foo()

Da mesma forma, use dir()para ver o conteúdo de um módulo ou os atributos de um objeto.

E ainda há mais.


4

Se você quiser examinar parâmetros e métodos, como outros já apontaram, você pode usar pprintoudir()

Se você quiser ver o valor real do conteúdo, pode fazer

object.__dict__


4

Duas ótimas ferramentas para inspeção de código são:

  1. IPython . Um terminal python que permite inspecionar usando o preenchimento de guias.

  2. Eclipse com o plugin PyDev . Possui um excelente depurador que permite que você quebre em um determinado local e inspecione objetos navegando em todas as variáveis ​​como uma árvore. Você pode até usar o terminal incorporado para tentar código nesse local ou digitar o objeto e pressionar '.' para dar dicas de código para você.

insira a descrição da imagem aqui



3

Existe uma compilação da biblioteca de códigos python apenas para esse propósito: inspecionar Introduzido no Python 2.7


3

Se você estiver interessado em ver o código fonte da função correspondente ao objeto myobj, digite iPythonou Jupyter Notebook:

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

ou

pprint.pprint(vars(obj))

Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre como e / ou por que resolve o problema melhoraria o valor a longo prazo da resposta.
Alexander Alexander

1

Se você deseja procurar dentro de um objeto ativo, o inspectmódulo do python é uma boa resposta. Em geral, ele funciona para obter o código fonte das funções definidas em um arquivo fonte em algum lugar do disco. Se você deseja obter a fonte de funções ativas e lambdas que foram definidas no intérprete, você pode usar dill.source.getsourcefrom dill. Ele também pode obter o código de métodos e funções de classe vinculados ou não definidos definidos em curries ... no entanto, talvez você não consiga compilar esse código sem o código do objeto que o encerra.

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 


0

Além disso, se você quiser procurar na lista e nos dicionários, use pprint ()


0

Muitas dicas boas já, mas a mais curta e fácil (não necessariamente a melhor) ainda não foi mencionada:

object?

-3

Tente usar:

print(object.stringify())
  • onde objecté o nome da variável do objeto que você está tentando inspecionar.

Isso imprime uma saída bem formatada e com guias, mostrando toda a hierarquia de chaves e valores no objeto.

NOTA: Isso funciona em python3. Não tenho certeza se funciona em versões anteriores

UPDATE: Isso não funciona em todos os tipos de objetos. Se você encontrar um desses tipos (como um objeto Request), use um dos seguintes procedimentos:

  • dir(object())

ou

import pprint então: pprint.pprint(object.__dict__)


1
Não funciona em um objeto 'Solicitação' "O objeto 'Solicitação' não tem atributo 'stringify'" "
AlxVallejo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.