Existe-t-il une fonction intégrée pour imprimer toutes les propriétés et valeurs actuelles d'un objet?
-
08-07-2019 - |
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.
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 larepr()
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 lastr()
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)
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é 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)