2009-06-17 15 views
168

Je commence à coder dans divers projets en utilisant Python (y compris le développement web Django et le développement de jeux Panda3D).Comment regarder à l'intérieur d'un objet Python?

Pour m'aider à comprendre ce qui se passe, j'aimerais fondamentalement «regarder» à l'intérieur des objets Python pour voir comment ils se comportent - comme leurs méthodes et leurs propriétés.

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

Répondre

46

Tout d'abord, lisez la source.

Ensuite, utilisez la fonction dir().

+60

Je renverser cet ordre. – bayer

+4

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

+11

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

6

Vous pouvez lister les attributs d'un objet avec dir() dans la coquille:

>>> 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 l'inspecter le module: http://docs.python.org/library/inspect.html#module-inspect

7
"""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__ 
+3

Cela fonctionne très bien en python 3 si vous ajoutez juste des parens autour des impressions. – ConstantineK

212

Python a un solide ensemble des caractéristiques d'introspection.

Jetez un oeil à la built-in functions suivante:

type() et dir() sont particulièrement utiles pour l'inspection du type d'un objet et de son ensemble d'attributs, respectivement.

+13

Je ne savais pas que le terme était «introspection». C'est une aide précieuse! Aussi bien que toutes les fonctions que vous m'avez données ... Merci! – littlejim84

+2

propriété, classmethod et staticmethod ne sont pas liés à l'introspection. Ces méthodes créent toutes des types spéciaux d'objets qui peuvent être utilisés pour définir des classes ayant un comportement spécial, mais qui ne facilitent pas l'inspection de ces classes ou constructions. – SingleNegationElimination

+0

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 peut être utile d'inclure une référence à sa réponse dans cette réponse, car c'est la plus acceptée.) – michaelavila

0

En outre, si vous voulez regarder à l'intérieur liste et dictionnaires, vous pouvez utiliser pprint()

2

pprint et dir travailler ensemble une grande

4

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

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

object.__dict__

17

Si c'est pour l'exploration de voir ce qui se passe, je vous recommande de regarder IPython. Cela ajoute plusieurs raccourcis pour obtenir une documentation d'objets, des propriétés et même du code source. Par exemple en ajoutant 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 l'achèvement des onglets, la jolie impression des résultats, l'historique des résultats, etc. qui le rendent très pratique pour ce genre de programmation exploratoire.

Pour une utilisation plus programmatique de l'introspection, les fonctions intégrées de base comme dir(), vars(), getattr etc seront utiles, mais il vaut bien votre temps pour vérifier le module inspect. Pour récupérer la source d'une fonction, utilisez « inspect.getsource » par exemple, l'appliquer à lui-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 aussi souvent utile si vous avez affaire à l'emballage ou la manipulation de fonctions, car il donnera les noms et défaut valeurs des paramètres de la fonction.

136

object.__dict__

+2

Ne fonctionne pas avec les emplacements –

+0

cela ne fonctionne pas. – Sajuuk

+0

Fonctionne pour moi (Python 3.6.2). – OmarOthman

6

D'autres ont déjà mentionné le répertoire() intégré qui ressemble à ce que vous cherchez, mais voici une autre bonne astuce. De nombreuses bibliothèques - y compris la plupart de la bibliothèque standard - sont distribuées sous forme de source. Cela signifie que vous pouvez facilement lire 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é, donc supprimer la fuite « c » et ouvrir le fichier .py * décompilé dans votre éditeur préféré ou visionneuse de fichiers:

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

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

40

Je suis surpris que personne n'a encore mentionné l'aide! L'aide vous permet de lire la docstring et d'avoir une idée des attributs d'une classe, ce qui est plutôt utile.

+2

Que faire si la méthode n'a pas de docstring, c'est-à-dire pas de documentation? – Sajuuk

1

Si vous voulez regarder à l'intérieur d'un objet live, alors le module inspect de python est une bonne réponse. En général, cela fonctionne pour obtenir le code source des fonctions qui sont définies dans un fichier source quelque part sur le disque. Si vous voulez obtenir la source des fonctions live et des lambdas définis dans l'interpréteur, vous pouvez utiliser dill.source.getsource depuis dill. Il peut également obtenir le code pour les méthodes et fonctions de classes liées ou non liées 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 

>>> 
2

Il y a une version bibliothèque de code python juste à cet effet: inspect Introduit en Python 2.7

10

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

objbrowserscreenshot

6

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) 

Sortie:

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

Deux grands outils pour le code d'inspection sont:

  1. IPython. Un terminal python qui vous permet d'inspecter en utilisant l'achèvement de l'onglet.

  2. Eclipse avec le PyDev plugin. Il a un excellent débogueur qui vous permet de casser à un endroit donné et inspecter des objets en parcourant toutes les variables comme un arbre. Vous pouvez même utiliser le terminal intégré pour essayer du code à cet endroit ou taper l'objet et appuyer sur '.' pour avoir des indications de code pour vous.

enter image description here

0

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

Questions connexes