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?

littlejim84
la source

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.

Brandon E Taylor
la source
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__

mtasic85
la source
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.

S.Lott
la source
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.

Jason Baker
la source
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.

Brian
la source
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

titusjan
la source
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

bayer
la source
8
"""Visit http://diveintopython.net/"""

__author__ = "Mark Pilgrim ([email protected])"


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__
erenon
la source
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
)
Symon
la source
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.

Ryan Bright
la source
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.

wp78de
la source
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__

Lakshman Prasad
la source
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

frmdstryr
la source
3

pprint et dir fonctionnent ensemble très bien

sqram
la source
3

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

Jonathan
la source
3

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

myobj??

Sahar
la source
2
import pprint

pprint.pprint(obj.__dict__)

ou

pprint.pprint(vars(obj))
northtree
la source
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

>>> 
Mike McKerns
la source
1

vars (obj) renvoie les attributs d'un objet.

Omid Farvid
la source
0

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

Glader
la source
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?
fmb
la source
-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__)

Ira Herman
la source
1
Ne fonctionne pas sur un objet 'Request' "L'objet 'Request' n'a pas d'attribut 'stringify'"
AlxVallejo