web-dev-qa-db-fra.com

Existe-t-il une fonction intégrée pour imprimer toutes les propriétés et valeurs actuelles d'un objet?

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.

754
fuentesjr

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__'}
472
user3850

Vous voulez vars() mélangé avec pprint():

from pprint import pprint
pprint(vars(your_object))
819
Jeremy Cantrell
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.

160
Dan Lenski

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}
45
eduffy

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ée repr() 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ée str() 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.

20
jfs

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
19
Joe Skora

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

15
Tel

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:

  • noms des paramètres de fonction et de méthode
  • hiérarchies de classes
  • code source de l'implémentation d'un objet de fonctions/classe
  • variables locales hors d'un objet cadre

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

11
William McVey

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.

7
jfs

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))
5
Adam Cath

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)
4
wisbucky

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?

3
Clark

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)
3
Symon

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])
3
DaOneTwo
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))
3
32ndghost

Pourquoi pas quelque chose de simple:

for key,value in obj.__dict__.iteritems():
    print key,value
2
Michael Thamm

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.

2
shahjapan

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)
2
Anyany Pan

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)

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.

2
Nagev

J'aime travailler avec les types intégrés d'objet Python keys ou values ​​

Pour les attributs, peu importe qu'ils soient des méthodes ou des variables: 

o.keys()

Pour les valeurs de ces attributs:

o.values()
0
Evhz

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))
0
Robert Hönig

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)
0
Slipstream