Question

Donc, ce que je recherche ici, c'est quelque chose comme la fonction print_r de PHP. C’est pour que je puisse déboguer mes scripts en consultant l’état de l’objet en question.

Était-ce utile?

La solution

Vous mélangez vraiment deux choses différentes.

Utilisez dir() , vars() ou le inspect module 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__'}

Autres conseils

Vous souhaitez vars() mélanger 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 souhaitez également connaître 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 des méthodes __str__ ou __repr__. De la documentation Python :

  

__repr__(self) Appelé par la repr() fonction intégrée et par la chaîne   conversions (guillemets inversés) en   calculer le " officiel " chaîne   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 (compte tenu d'un   environnement). Si ce n'est pas possible,   une chaîne de la forme " < ... un peu utile   description ... > " devrait être retourné.   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 un " informel " chaîne   représentation d'instances de cette   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 str() fonction intégrée et par le caractère d'impression   instruction pour calculer le " informel "   représentation sous forme de chaîne d'un objet.   Cela diffère de <=> en ce que   il n'est pas nécessaire que ce soit un Python valide   expression: un plus commode ou   une représentation concise peut être utilisée   au lieu. La valeur de retour doit être un   objet string.

Vous pouvez utiliser le " dir () " fonction 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']
>>>

L'aide est une autre fonctionnalité utile.

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

Ça vaut peut-être le coup de chercher -

Existe-t-il un équivalent Python de Data :: Dumper, 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 les fonctions de méthode d'objet sortie). Ceci 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 ne réussit pas à obtenir, en particulier, il arrête simplement de descendre lorsqu'il voit une instance d'un objet et vous donne le pointeur hexagonal interne de l'objet (errr, ce pointeur n'est pas un lot entier). d’utilisation en passant). En résumé, python concerne tout ce formidable paradigme orienté objet, mais les outils que vous obtenez sont conçus pour travailler 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, utiliser __dict__ ou dir() vous permettra d'obtenir les informations souhaitées. Si vous avez besoin de plus de détails, la bibliothèque standard inclut le module inspect , ce 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 ne recherchez que & ", quelles sont les valeurs d'attributs de mon objet? &" ;, alors inspect et <=> sont probablement suffisants. Si vous souhaitez vraiment explorer l'état actuel des objets arbitraires (en gardant à l'esprit qu'en Python, presque tout est objet), alors <=> est digne de considération.

Exemple de métaprogrammation Dump d'un objet avec de la magie :

$ 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 arguments:

$ python dump.py
<__main__.Data instance at 0x00A052D8>

Avec les utilitaires de la gnose :

$ 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>

Il est un peu désuet 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 est insatisfaisante car elle nécessite déjà que vos classes aient une bonne implémentation __ 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 imprime tous les contenus d'objet de manière récursive au format JSON ou YAML indenté:

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)

Je recommande d'utiliser help (votre_objet) .

help (dir)

 If called without an argument, return the names in the current scope.
 Else, return an alphabetized list of names comprising (some of) the attributes
 of the given object, and of attributes reachable from it.
 If the object supplies a method named __dir__, it will be used; otherwise
 the default dir() logic is used and returns:
 for a module object: the module's attributes.
 for a class object:  its attributes, and recursively the attributes
 of its bases.
 for any other object: its attributes, its class's attributes, and
 recursively the attributes of its class's base classes.

help (vars)

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

J'avais besoin d'imprimer les informations DEBUG dans certains journaux et je ne pouvais pas utiliser pprint car cela le casserait. Au lieu de cela, j’ai fait cela et obtenu pratiquement la même chose.

DO = DemoObject()

itemDir = DO.__dict__

for i in itemDir:
    print '{0}  :  {1}'.format(i, itemDir[i])

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 non JSON sérialisable" ; en python?

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

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)

pprint contient une & # 8220; jolie imprimante & # 8221; pour 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.

Pourquoi pas quelque chose de simple:

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

J'ai voté en faveur de la réponse qui ne mentionne que pprint. Pour être clair, si vous voulez voir toutes les valeurs dans une structure de données complexe, procédez comme suit:

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é inutilement longue. En passant, dans mon cas particulier, le code que je vérifiais avait un dictionnaire de dictionnaires.

Il est intéressant de noter qu'avec certaines classes personnalisées, vous risquez de vous retrouver avec un objet < someobject.ExampleClass inutile à 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.

Il suffit d’essayer beeprint .

Cela vous aidera non seulement à imprimer des variables d'objet, mais également à produire de belles sorties, comme ceci:

class(NormalClassNewStyle):
  dicts: {
  },
  lists: [],
  static_props: 1,
  tupl: (1, 2)

Pour tout le monde aux prises avec

  • vars () ne renvoie pas tous les attributs.
  • dir () ne renvoie pas les valeurs des attributs.

Le code suivant imprime tous 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)

J'aime travailler avec les types intégrés d'objet Python clés ou valeurs .

Pour les attributs, qu’ils soient des méthodes ou des variables:

o.keys()

Pour les valeurs de ces attributs:

o.values()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top