Je commence à coder dans divers projets en utilisant Python (y compris Django développement Web et développement de jeux Panda3D).
Pour m'aider à comprendre ce qui se passe, j'aimerais simplement "regarder" à l'intérieur des objets Python pour voir comment ils fonctionnent - comme leurs méthodes et leurs propriétés.
Alors disons que j’ai un objet Python, de quoi aurais-je besoin pour imprimer son contenu? Est-ce que c'est possible?
Python possède un ensemble complet de fonctionnalités d’introspection.
Jetez un oeil à ce qui suit fonctions intégrées :
type()
et dir()
sont particulièrement utiles pour inspecter le type d'un objet et son ensemble d'attributs, respectivement.
object.__dict__
Tout d'abord, lisez la source.
Deuxièmement, utilisez la fonction dir()
.
Je suis surpris que personne n'ait encore mentionné l'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 que peut avoir une classe, ce qui est très utile.
Si ceci est à explorer pour voir ce qui se passe, je vous conseillerais de regarder IPython . Cela ajoute divers raccourcis pour obtenir une documentation sur les objets, des propriétés et même du code source. Par exemple en ajoutant un "?" à une fonction donnera l'aide pour l'objet (effectivement un raccourci pour "aide (obj)", alors que l'utilisation de deux? ("func??
") affichera le code source s'il est disponible.
Il existe également de nombreuses commodités supplémentaires, telles que 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 type de programmation exploratoire.
Pour une utilisation plus programmatique de l'introspection, les fonctions de base telles que dir()
, vars()
, getattr
etc seront utiles, mais vous aurez tout intérêt à jeter un œil à la inspecter module. Pour récupérer le source d'une fonction, utilisez "inspect.getsource
", par exemple, en l'appliquant à 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 également souvent utile si vous manipulez ou modifiez des fonctions, car il donnera les noms et les valeurs par défaut des paramètres de fonction.
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'objets en dessous.
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 inspecter: http://docs.python.org/library/inspect.html#module-inspect
"""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 __== "__main__":
print help.__doc__
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
)
D'autres ont déjà mentionné la commande intégrée dir () qui ressemble à ce que vous recherchez, mais voici un autre bon conseil. De nombreuses bibliothèques - y compris la plupart des bibliothèques standard - sont distribuées sous forme source. Cela signifie que vous pouvez facilement lire le code source directement. Le truc est de le trouver; par exemple:
>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'
Le fichier * .pyc étant compilé, supprimez le "c" de fin et ouvrez le fichier * .py non compilé dans votre éditeur ou visionneuse de fichiers préféré:
/usr/lib/python2.5/string.py
J'ai trouvé cela extrêmement utile pour découvrir des éléments tels que les exceptions déclenchées à partir d'une API donnée. Ce genre de détail est rarement bien documenté dans le monde Python.
Bien que pprint
ait déjà été mentionné par d'autres, j'aimerais ajouter un peu de contexte.
Le module pprint permet de "joliment imprimer" des structures de données Python arbitraires dans un formulaire pouvant être utilisé comme entrée pour l'interpréteur. Si les structures formatées incluent des objets qui ne sont pas des types fondamentaux Python, la représentation risque de 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.
pprint
pourrait être très demandé par les développeurs ayant un background de PHP qui recherchent une alternative à var_dump()
.
Les objets avec un attribut dict peuvent être facilement sauvegardés en utilisant pprint()
mélangé à vars()
, qui renvoie l'attribut __dict__
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 locale globale ou , utilisez simplement:
pprint(globals())
pprint(locals())
locals()
affiche les variables définies dans une fonction.
Il est également utile d’accéder aux fonctions portant le 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 a encore plus.
Si vous souhaitez examiner les paramètres et les méthodes, comme d'autres l'ont déjà indiqué, vous pouvez utiliser pprint
ou dir()
.
Si vous voulez voir la valeur réelle du contenu, vous pouvez faire
object.__dict__
Il existe une bibliothèque de code python uniquement à cet effet: inspect Introduit dans Python 2.7
Deux excellents outils pour inspecter le code sont:
IPython . Un terminal python qui vous permet d'inspecter à l'aide de la complétion par tabulation.
Eclipse avec le plugin PyDev . Il possède un excellent débogueur qui vous permet de casser à un endroit donné et d'inspecter des objets en parcourant toutes les variables sous forme d'arborescence. Vous pouvez même utiliser le terminal intégré pour essayer du code à cet endroit ou taper l'objet et appuyer sur '.' l'avoir donner des conseils de code pour vous.
pprint et dir ensemble fonctionnent très bien
Si vous êtes intéressé à voir le code source de la fonction correspondant à l'objet myobj
, vous pouvez taper iPython
ou Jupyter Notebook
:
myobj??
vars (obj) renvoie les attributs d'un objet.
Si vous voulez regarder à l'intérieur d'un objet vivant, 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 actives et des lambdas définis dans l'interpréteur, vous pouvez utiliser dill.source.getsource
à partir de dill
. Il peut également obtenir le code pour les méthodes et fonctions de classe 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
>>>
import pprint
pprint.pprint(obj.__dict__)
ou
pprint.pprint(vars(obj))
De plus, si vous voulez regarder dans la liste et les dictionnaires, vous pouvez utiliser pprint ()