Donc, ce que je recherche ici est quelque chose comme la fonction print_r de PHP. C'est pour que je puisse déboguer mes scripts en vérifiant l'état de l'objet en question.
Vous mélangez vraiment deux choses différentes.
Utilisez dir()
, vars()
ou le module inspect
pour obtenir ce qui vous intéresse (j'utilise __builtins__
à titre d'exemple; vous pouvez utiliser n'importe quel objet à la place).
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__
Imprimez ce dictionnaire comme bon vous semble:
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...
ou
>>> from pprint import pprint
>>> pprint(l)
['ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
>>> pprint(d, indent=2)
{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
...
'_': [ 'ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
La jolie impression est également disponible dans le débogueur interactif en tant que commande:
(Pdb) pp vars()
{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
'BaseException': <type 'exceptions.BaseException'>,
'BufferError': <type 'exceptions.BufferError'>,
...
'Zip': <built-in function Zip>},
'__file__': 'pass.py',
'__name__': '__main__'}
Vous voulez vars()
mélangé avec pprint()
:
from pprint import pprint
pprint(vars(your_object))
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
Il existe de nombreuses fonctions tierces qui ajoutent des éléments tels que la gestion des exceptions, l'impression de caractères nationaux/spéciaux, la récurrence dans des objets imbriqués, etc. selon les préférences de leurs auteurs. Mais ils se résument tous à cela.
dir a été mentionné, mais cela ne vous donnera que les noms des attributs. Si vous voulez aussi leurs valeurs, essayez __dict__.
class O:
def __init__ (self):
self.value = 3
o = O()
Voici la sortie:
>>> o.__dict__
{'value': 3}
Pour imprimer l'état actuel de l'objet, vous pouvez:
>>> obj # in an interpreter
ou
print repr(obj) # in a script
ou
print obj
Pour vos classes, définissez les méthodes __str__
ou __repr__
. Depuis la documentation Python :
__repr__(self)
Appelé par la fonction intégréerepr()
et par la chaîne conversions (guillemets inverses) en calcule la chaîne "officielle" représentation d'un objet. Si du tout possible, cela devrait ressembler à un expression Python valide qui pourrait être utilisé pour recréer un objet avec le même valeur (étant donné un environnement approprié ). Si ce n'est pas possible, une chaîne de la forme "<... une partie utile description ...>" doit être renvoyée . La valeur de retour doit être une chaîne objet. Si une classe définit repr () mais pas__str__()
, alors__repr__()
est également utilisé quand une chaîne "informelle" représentation des instances de cela la classe est obligatoire. C'est typiquement utilisé pour le débogage, il est donc important que la représentation est riche en informations et sans ambiguïté.
__str__(self)
Appelé par la fonction intégréestr()
et par l’impression déclaration pour calculer le "informel" représentation sous forme de chaîne d'un objet . Cela diffère de__repr__()
en ce que il n'est pas nécessaire que ce soit un Python valide expression: un plus pratique ou une représentation concise peut être utilisée au lieu. La valeur de retour doit être un objet string.
Vous pouvez utiliser la fonction "dir ()" pour le faire.
>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdo
t__', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder
, 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info'
'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefault
ncoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'he
version', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_
ache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
, 'settrace', 'stderr', 'stdin', 'stdout', 'Subversion', 'version', 'version_info', 'warnoption
', 'winver']
>>>
Une autre fonctionnalité utile est l'aide.
>>> help(sys)
Help on built-in module sys:
NAME
sys
FILE
(built-in)
MODULE DOCS
http://www.python.org/doc/current/lib/module-sys.html
DESCRIPTION
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.
Dynamic objects:
argv -- command line arguments; argv[0] is the script pathname if known
Cela vaut peut-être la peine de vérifier -
Y a-t-il un équivalent Python à Data :: Dumper de Perl?
Ma recommandation est la suivante -
https://Gist.github.com/1071857
Notez que Perl a un module appelé Data :: Dumper qui convertit les données d'objet en code source Perl (NB: il ne convertit PAS le code en source, et vous ne voulez presque toujours pas que la méthode de l'objet fonctionne dans la sortie). Cela peut être utilisé pour la persistance, mais le but commun est le débogage.
Il y a un certain nombre de choses que python standard n'obtient pas, en particulier il arrête de descendre quand il voit une instance d'un objet et vous donne le pointeur hexagonal interne de l'objet (errr, ce pointeur n'est pas très utilisé par le chemin). En résumé, python concerne tout ce formidable paradigme orienté objet, mais les outils que vous obtenez immédiatement sont conçus pour fonctionner avec autre chose que des objets.
Perl Data :: Dumper vous permet de contrôler la profondeur à laquelle vous voulez aller, et détecte également les structures liées circulaires (c’est très important). Ce processus est fondamentalement plus facile à réaliser en Perl car les objets n’ont pas de magie particulière au-delà de leur bénédiction (processus universellement bien défini).
Dans la plupart des cas, en utilisant __dict__
ou dir()
, vous obtiendrez les informations souhaitées. Si vous avez besoin de plus de détails, la bibliothèque standard inclut le module inspect , qui vous permet d’obtenir une quantité impressionnante de détails. Parmi les véritables pépites d’informations, citons:
Si vous recherchez simplement "quelles valeurs d'attribut mon objet a-t-il?", Alors dir()
et __dict__
sont probablement suffisants. Si vous cherchez vraiment à plonger dans l'état actuel des objets arbitraires (en gardant à l'esprit que presque tout est un objet en python), alors inspect
mérite d'être considéré.
Un exemple de métaprogrammation Dump objet with magic :
$ cat dump.py
#!/usr/bin/python
import sys
if len(sys.argv) > 2:
module, metaklass = sys.argv[1:3]
m = __import__(module, globals(), locals(), [metaklass])
__metaclass__ = getattr(m, metaklass)
class Data:
def __init__(self):
self.num = 38
self.lst = ['a','b','c']
self.str = 'spam'
dumps = lambda self: repr(self)
__str__ = lambda self: self.dumps()
data = Data()
print data
Sans argument:
$ python dump.py
<__main__.Data instance at 0x00A052D8>
Avec Utilités Gnosis :
$ python dump.py gnosis.magic MetaXMLPickler
<?xml version="1.0"?>
<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">
<PyObject module="__main__" class="Data" id="11038416">
<attr name="lst" type="list" id="11196136" >
<item type="string" value="a" />
<item type="string" value="b" />
<item type="string" value="c" />
</attr>
<attr name="num" type="numeric" value="38" />
<attr name="str" type="string" value="spam" />
</PyObject>
C'est un peu démodé mais fonctionne toujours.
Si vous utilisez ceci pour le débogage et que vous voulez juste un vidage récursif de tout, la réponse acceptée n'est pas satisfaisante car elle nécessite que vos classes aient déjà une bonne implémentation de __str__
. Si ce n'est pas le cas, cela fonctionne beaucoup mieux:
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
Ceci affiche tous les contenus d'objet de manière récursive au format JSON ou YAML en retrait
import jsonpickle # pip install jsonpickle
import json
import yaml # pip install pyyaml
serialized = jsonpickle.encode(obj, max_depth=2) # max_depth is optional
print json.dumps(json.loads(serialized), indent=4)
print yaml.dump(yaml.load(serialized), indent=4)
Pour vider "monObjet":
from bson import json_util
import json
print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))
J'ai essayé vars () et dir (); les deux ont échoué pour ce que je cherchais. vars () n'a pas fonctionné car l'objet n'avait pas __dict__ (l'argument exceptions.TypeError: vars () doit avoir l'attribut __dict__). dir () n'était pas ce que je cherchais: c'est juste une liste de noms de champs, ne donne pas les valeurs ni la structure de l'objet.
Je pense que json.dumps () fonctionnerait pour la plupart des objets sans la valeur par défaut = json_util.default, mais j'avais un champ date/heure dans l'objet, de sorte que le sérialiseur json standard a échoué. Voir Comment surmonter "datetime.datetime pas JSON sérialisable" en python?
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(), show_protected=True, show_static=True, show_properties=True)
Sortie:
__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)
J'avais besoin d'imprimer les informations de débogage dans certains journaux et je ne pouvais pas utiliser pprint car cela le casserait. Au lieu de cela, je l'ai fait et j'ai obtenu pratiquement la même chose.
DO = DemoObject()
itemDir = DO.__dict__
for i in itemDir:
print '{0} : {1}'.format(i, itemDir[i])
from pprint import pprint
def print_r(the_object):
print ("CLASS: ", the_object.__class__.__name__, " (BASE CLASS: ", the_object.__class__.__bases__,")")
pprint(vars(the_object))
Pourquoi pas quelque chose de simple:
for key,value in obj.__dict__.iteritems():
print key,value
pprint contient une "jolie imprimante" permettant de produire des représentations esthétiques de vos structures de données. Le formateur produit des représentations de structures de données qui peuvent être analysées correctement par l’interprète et qui sont également faciles à lire. La sortie est conservée sur une seule ligne, si possible, et en retrait lorsqu'elle est fractionnée sur plusieurs lignes.
Essayez juste beeprint .
Cela vous aidera non seulement à imprimer des variables d'objet, mais aussi à obtenir une belle sortie, comme ceci:
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)
J'ai voté en faveur de la réponse qui ne mentionne que pprint. Pour être clair, si vous voulez voir tous les values dans une structure de données complexe, faites quelque chose comme:
from pprint import pprint
pprint(my_var)
Où my_var est votre variable d'intérêt. Quand j'ai utilisé pprint (vars (my_var)), je n'ai rien reçu, et les autres réponses ici n'ont pas aidé ou la méthode a semblé trop longue. En passant, dans mon cas particulier, le code que j'ai inspecté avait un dictionnaire de dictionnaires.
Il est intéressant de noter qu'avec certaines classes personnalisées, vous risquez de vous retrouver avec un type de sortie peu utile <someobject.ExampleClass object at 0x7f739267f400>
. Dans ce cas, vous devrez peut-être implémenter une méthode __str__
ou essayer d'autres solutions. J'aimerais toujours trouver quelque chose de simple qui fonctionne dans tous les scénarios, sans bibliothèques tierces.
Pour tout le monde aux prises avec
vars()
ne renvoyant pas tous les attributs. dir()
ne renvoyant pas les valeurs des attributs.Le code suivant imprime tout les attributs de obj
avec leurs valeurs:
for attr in dir(obj):
try:
print("obj.{} = {}".format(attr, getattr(obj, attr)))
except AttributeError:
print("obj.{} = ?".format(attr))
Vous pouvez essayer la barre d'outils de débogage Flask.
https://pypi.python.org/pypi/Flask-DebugToolbar
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
app = Flask(__name__)
# the toolbar is only enabled in debug mode:
app.debug = True
# set a 'SECRET_KEY' to enable the Flask session cookies
app.config['SECRET_KEY'] = '<replace with a secret key>'
toolbar = DebugToolbarExtension(app)