Comment regarder à l'intérieur d'un objet Python?


291

Je commence à coder dans divers projets utilisant Python (y compris le développement web Django et le développement de jeux Panda3D).

Pour m'aider à comprendre ce qui se passe, je voudrais essentiellement 'regarder' à l'intérieur des objets Python pour voir comment ils fonctionnent - comme leurs méthodes et propriétés.

Disons que j'ai un objet Python, de quoi aurais-je besoin pour imprimer son contenu? Est-ce que c'est possible?

Réponses:


352

Python possède un ensemble solide de fonctionnalités d'introspection.

Jetez un œil aux fonctions intégrées suivantes :

type()et dir()sont particulièrement utiles pour inspecter le type d'un objet et son ensemble d'attributs, respectivement.


25
Je ne savais pas que le terme était «introspection». C'est une grande aide! Aussi bien que tous les fonctons que vous m'avez donnés ... Merci!
littlejim84

2
La propriété, la méthode de classe et la méthode statique ne sont pas liées à l'introspection. Ces méthodes créent toutes des types spéciaux d'objets qui peuvent être utilisés pour définir des classes avec un comportement spécial, mais ne sont d'aucune utilité pour inspecter ces classes ou constructions.
SingleNegationElimination

La réponse de @Brian ci-dessous vous montre comment afficher également le code source de divers objets python à partir de python. C'est ce que je cherchais à l'origine et je suis sûr que je ne serai pas seul. (Il pourrait être utile d'inclure une référence à sa réponse dans cette réponse car c'est la plus acceptée.)
michaelavila

C'est comme "IntelliSense" intégré pour python. J'aime cela.
Bruno Bieri

7
je pense que c'est une mauvaise réponse. au lieu de nous donner une solution, cela nous donne juste tout ce qui est lié à cela dans la documentation
Ishan Srivastava

176

object.__dict__


12
vars(object)est fait pour ça.
liberforce

6
En from pprint import pprint; pprint(vars(object))fait, cela m'a donné une très belle vue sur le contenu de mon objet. Merci @liberforce
N. Maks

la meilleure façon de voir l'objet et son contenu dans une chaîne
Peter Krauss

C'est un excellent moyen de voir des objets qui implémentent des méthodes de représentation, ou des objets comme googleapiclient.errors.HttpError qui, lorsque vous les imprimez, impriment à coup sûr des informations insuffisantes, merci @ mtasic85
Felipe Valdes

65

Tout d'abord, lisez la source.

Deuxièmement, utilisez la dir()fonction.


92
Je renverserais cet ordre.
bayer

5
La source est plus informative que dir () et une meilleure habitude à développer.
S.Lott

14
Je ne suis pas d'accord. dir () est tellement plus rapide et dans 99% des cas, vous trouverez ce dont vous avez besoin en combinaison avec help ().
bayer

7
Je suis d'accord avec habituellement inutile. La plupart du temps, un simple appel à dir () suffira, vous évitant ainsi d'avoir à parcourir le code source.
Sasha Chedygov

3
Parfois, inspecter des objets au moment de l'exécution peut être utile, mais pas la lecture des sources. Par exemple, les classes httplib.py et leurs méthodes :).
Denis Barmenkov

61

Je suis surpris que personne n'ait encore mentionné d'aide!

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

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

foo()
    foo!

L'aide vous permet de lire la docstring et d'avoir une idée des attributs qu'une classe peut avoir, ce qui est très utile.


Ensuite, vous utilisez les autres techniques mentionnées ici. Mais si la docstring est disponible, considérez-la comme canon.
Edward Falk

Je ne sais pas si python a mis à jour cette fonction au cours des dernières années, mais "help (object_name)" fournit un aperçu complet dans un format hautement structuré. C'est un gardien. Merci.
Brian Cugelman

27

Si c'est pour l'exploration pour voir ce qui se passe, je recommanderais de regarder IPython . Cela ajoute divers raccourcis pour obtenir une documentation des objets, des propriétés et même du code source. Par exemple, ajouter un "?" à une fonction donnera l'aide pour l'objet (en fait un raccourci pour "help (obj)", alors que l'utilisation de deux? (" func??") affichera le code source s'il est disponible.

Il y a aussi beaucoup de commodités supplémentaires, comme la complétion des onglets, la jolie impression des résultats, l'historique des résultats, etc. qui le rendent très pratique pour ce type de programmation exploratoire.

Pour une utilisation plus programmatique de l' introspection, les builtins de base comme dir(), vars(), getattretc sera utile, mais il vaut bien votre temps pour vérifier le inspectent module. Pour récupérer la source d'une fonction, utilisez " inspect.getsource" par exemple, en l'appliquant à elle-même:

>>> 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 est également souvent utile si vous traitez ou manipulez des fonctions, car il donnera les noms et les valeurs par défaut des paramètres de fonction.


18

Si vous êtes intéressé par une interface graphique pour cela, jetez un œil à objbrowser . Il utilise le module d'inspection de la bibliothèque standard Python pour l'introspection d'objets en dessous.

objbrowserscreenshot


9

Vous pouvez lister les attributs d'un objet avec dir () dans le shell:

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

Bien sûr, il y a aussi le module d'inspection: 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
Cela fonctionne très bien en python 3 si vous ajoutez simplement des parens autour des impressions.
ConstantineK

8

Essayez 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)

Production:

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

7

D'autres ont déjà mentionné le dir () intégré qui ressemble à ce que vous recherchez, mais voici un autre bon conseil. De nombreuses bibliothèques - dont la plupart des bibliothèques standard - sont distribuées sous forme source. Cela signifie que vous pouvez lire assez facilement le code source directement. L'astuce consiste à le trouver; par exemple:

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

Le fichier * .pyc est compilé, supprimez donc le «c» de fin et ouvrez le fichier * .py non compilé dans votre éditeur ou visualiseur de fichiers préféré:

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

J'ai trouvé cela incroyablement utile pour découvrir des choses comme les exceptions qui sont déclenchées à partir d'une API donnée. Ce genre de détail est rarement bien documenté dans le monde Python.


7

Bien que cela pprintait déjà été mentionné par d'autres, j'aimerais ajouter un peu de contexte.

Le module pprint offre la possibilité de «joliment imprimer» des structures de données Python arbitraires sous une forme qui peut être utilisée comme entrée pour l'interpréteur. Si les structures formatées incluent des objets qui ne sont pas des types Python fondamentaux, la représentation peut ne pas être chargeable. Cela peut être le cas si des objets tels que des fichiers, des sockets, des classes ou des instances sont inclus, ainsi que de nombreux autres objets intégrés qui ne sont pas représentables en tant que constantes Python.

pprintpourrait être très demandé par les développeurs ayant une expérience PHP qui recherchent une alternative à var_dump().

Les objets avec un attribut dict peuvent être bien vidés en utilisant pprint()mixé avec vars(), qui retourne l' __dict__attribut pour un module, une classe, une instance, etc.:

from pprint import pprint
pprint(vars(your_object))

Donc, pas besoin de boucle .

Pour vider toutes les variables contenues dans la portée globale ou locale, utilisez simplement:

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

locals()affiche les variables définies dans une fonction.
Il est également utile d'accéder aux fonctions avec leur nom correspondant sous forme de clé de chaîne, entre autres utilisations :

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

De même, utilisez dir()pour voir le contenu d'un module ou les attributs d'un objet.

Et il y en a encore plus.


4

Si vous voulez regarder les paramètres et les méthodes, comme d' autres l' ont souligné , vous pouvez bien utiliser pprintoudir()

Si vous voulez voir la valeur réelle du contenu, vous pouvez faire

object.__dict__


4

Deux excellents outils pour inspecter le code sont:

  1. IPython . Un terminal python qui vous permet d'inspecter à l'aide de la complétion de tabulation.

  2. Eclipse avec le plugin PyDev . Il dispose d'un excellent débogueur qui vous permet de vous interrompre à un endroit donné et d'inspecter des objets en parcourant toutes les variables sous forme d'arbre. Vous pouvez même utiliser le terminal intégré pour essayer le code à cet endroit ou taper l'objet et appuyez sur "." pour qu'il vous donne des conseils de code.

entrez la description de l'image ici


3

pprint et dir fonctionnent ensemble très bien


3

Il existe une bibliothèque de code python spécialement conçue à cet effet: inspect Introduit dans Python 2.7


3

Si vous souhaitez voir le code source de la fonction correspondant à l'objet myobj, vous pouvez taper iPythonou Jupyter Notebook:

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

ou

pprint.pprint(vars(obj))

Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la manière et / ou la raison pour laquelle il résout le problème améliorerait la valeur à long terme de la réponse.
Alexander

1

Si vous voulez regarder à l'intérieur d'un objet en direct, le inspectmodule de python est une bonne réponse. En général, cela fonctionne pour obtenir le code source des fonctions définies dans un fichier source quelque part sur le disque. Si vous souhaitez obtenir la source des fonctions en direct et des lambdas définis dans l'interpréteur, vous pouvez utiliser à dill.source.getsourcepartir de dill. Il peut également obtenir le code des méthodes et fonctions de classe liées ou non définies définies dans les currys ... cependant, vous ne pourrez peut-être pas compiler ce code sans le code de l'objet englobant.

>>> 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

De plus, si vous souhaitez consulter la liste et les dictionnaires, vous pouvez utiliser pprint ()


0

Beaucoup de bons conseils déjà, mais le plus court et le plus facile (pas nécessairement le meilleur) n'a pas encore été mentionné:

object?

-3

Essayez d'utiliser:

print(object.stringify())
  • objectest le nom de variable de l'objet que vous essayez d'inspecter.

Cela imprime une sortie bien formatée et tabulée montrant toute la hiérarchie des clés et des valeurs dans l'objet.

REMARQUE: cela fonctionne en python3. Je ne sais pas si cela fonctionne dans les versions antérieures

MISE À JOUR: Cela ne fonctionne pas sur tous les types d'objets. Si vous rencontrez l'un de ces types (comme un objet Request), utilisez plutôt l'un des éléments suivants:

  • dir(object())

ou

import pprint puis: pprint.pprint(object.__dict__)


1
Ne fonctionne pas sur un objet 'Request' "L'objet 'Request' n'a pas d'attribut 'stringify'"
AlxVallejo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.