Réponses:
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__
comme 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__'}
print re.compile(r'slots').search('No slots here either.').__slots__
inspect
module dans votre réponse? Je pense que c'est la chose la plus proche de print_r ou var_dump.
dir()
, alors? dir()
renvoie uniquement une liste de noms, et tous ceux-ci n'existent pas dans vars()
ou dans l' __dict__
attribut.
Vous voulez vars()
mélanger avec pprint()
:
from pprint import pprint
pprint(vars(your_object))
vars()
retourne simplement le __dict__
de son argument et c'est aussi la solution de secours dir()
en cas d'absence de __dir__
méthode. utilisez donc dir()
en premier lieu, comme je l'ai dit.
dir()
vous donne toutes les choses intégrées que vous n'aimez probablement pas comme __str__
et __new__
. var()
non.
__dict__
attribut.
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.
getmembers()
fonction dans le inspect
module standard , mais je pensais que cela serait plus utile car il illustre comment faire de l'introspection en général.
__dict__
(comme __doc__
et __module__
). De plus, __dict__
ne fonctionne pas du tout pour les objets déclarés avec __slots__
. En général, __dict__
affiche les propriétés de niveau utilisateur qui sont réellement stockées dans un dictionnaire en interne. dir () en montre plus.
__dict__
attribut / membre. Je sais que c'est fou, mais vrai. Les éléments intégrés tels que int
et str
ou re.MatchObject
s sont des exemples courants. Essayez 'hello'.__dict__
, puis essayezdir('hello')
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}
set
ça n'en ont pas __dict__
, donc pour eux ça échouera avecAttributeError: 'set' object has no attribute '__dict__'
Vous pouvez utiliser la fonction "dir ()" pour ce 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
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éfinir __str__
ou __repr__
méthodes. Dans la documentation Python :
__repr__(self)
Appelé par larepr()
fonction intégrée et par les conversions de chaînes (guillemets inversés) pour calculer la représentation de chaîne "officielle" d'un objet. Si possible, cela devrait ressembler à une expression Python valide qui pourrait être utilisée pour recréer un objet avec la même valeur (dans un environnement approprié). Si cela n'est pas possible, une chaîne de la forme "<... une description utile ...>" doit être retournée. La valeur de retour doit être un objet chaîne. Si une classe définit repr () mais pas__str__()
, elle__repr__()
est également utilisée lorsqu'une représentation sous forme de chaîne "informelle" des instances de cette classe est requise. Ceci est généralement utilisé pour le débogage, il est donc important que la représentation soit riche en informations et sans ambiguïté.
__str__(self)
Appelé par lastr()
fonction intégrée et par l'instruction print pour calculer la représentation de chaîne "informelle" d'un objet. Cela diffère du__repr__()
fait qu'il ne doit pas nécessairement s'agir d'une expression Python valide: une représentation plus pratique ou concise peut être utilisée à la place. La valeur de retour doit être un objet chaîne.
print "DEBUG: object value: " + repr(obj)
Cela vaut peut-être la peine d'être vérifié -
Existe-t-il un Python équivalent à Perl's Data :: Dumper?
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 presque toujours vous ne voulez pas que les fonctions de méthode objet 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 pprint python standard ne parvient pas à réaliser, en particulier il arrête simplement de descendre lorsqu'il voit une instance d'un objet et vous donne le pointeur hexadécimal interne de l'objet (errr, ce pointeur n'est pas très utilisé par le chemin). Donc, en un mot, python concerne tout ce grand paradigme orienté objet, mais les outils que vous sortez de la boîte sont conçus pour travailler avec autre chose que des objets.
Le Perl Data :: Dumper vous permet de contrôler jusqu'à quelle profondeur vous voulez aller, et détecte également les structures liées circulaires (c'est vraiment 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 (un processus universellement bien défini).
Je recommande d'utiliser help(your_object)
.
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__.
Dans la plupart des cas, en utilisant __dict__
ou dir()
vous obtiendrez les informations que vous recherchez. Si vous avez besoin de plus de détails, la bibliothèque standard comprend le module d' inspection , qui vous permet d'obtenir une quantité impressionnante de détails. Certains des vrais pépites d'informations comprennent:
Si vous cherchez simplement "quelles valeurs d'attribut mon objet a-t-il?", Alors dir()
et __dict__
sont probablement suffisantes. Si vous cherchez vraiment à creuser dans l'état actuel des objets arbitraires (en gardant à l'esprit qu'en python presque tout est un objet), alors cela inspect
mérite d'être considéré.
Existe-t-il une fonction intégrée pour imprimer toutes les propriétés et valeurs actuelles d'un objet?
Non. La réponse la plus votée exclut certains types d'attributs et la réponse acceptée montre comment obtenir tous les attributs, y compris les méthodes et les parties de l'API non publique. Mais il n'y a pas de bonne fonction intégrée complète pour cela.
Donc, le court corollaire est que vous pouvez écrire le vôtre, mais il calculera les propriétés et autres descripteurs de données calculés qui font partie de l'API publique, et vous ne voudrez peut-être pas que:
from pprint import pprint
from inspect import getmembers
from types import FunctionType
def attributes(obj):
disallowed_names = {
name for name, value in getmembers(type(obj))
if isinstance(value, FunctionType)}
return {
name: getattr(obj, name) for name in dir(obj)
if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
def print_attributes(obj):
pprint(attributes(obj))
Observez l'application de la réponse actuellement la plus votée sur une classe avec beaucoup de différents types de membres de données:
from pprint import pprint
class Obj:
__slots__ = 'foo', 'bar', '__dict__'
def __init__(self, baz):
self.foo = ''
self.bar = 0
self.baz = baz
@property
def quux(self):
return self.foo * self.bar
obj = Obj('baz')
pprint(vars(obj))
imprime uniquement:
{'baz': 'baz'}
Parce vars
que ne renvoie que l' __dict__
objet d'un objet, et ce n'est pas une copie, donc si vous modifiez le dict retourné par vars, vous modifiez également __dict__
l'objet de l'objet lui-même.
vars(obj)['quux'] = 'WHAT?!'
vars(obj)
Retour:
{'baz': 'baz', 'quux': 'WHAT?!'}
- ce qui est mauvais car quux est une propriété que nous ne devrions pas définir et ne devrions pas être dans l'espace de noms ...
Appliquer les conseils dans la réponse actuellement acceptée (et dans d'autres) n'est pas beaucoup mieux:
>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar', 'baz', 'foo', 'quux']
Comme nous pouvons le voir, dir
ne renvoie que tous (en fait juste la plupart) des noms associés à un objet.
inspect.getmembers
, mentionné dans les commentaires, est également imparfait - il renvoie tous les noms et valeurs.
Lorsque j'enseigne, mes élèves créent une fonction qui fournit l'API sémantiquement publique d'un objet:
def api(obj):
return [name for name in dir(obj) if name[0] != '_']
Nous pouvons étendre cela pour fournir une copie de l'espace de noms sémantique d'un objet, mais nous devons exclure ceux __slots__
qui ne sont pas attribués, et si nous prenons au sérieux la demande de "propriétés actuelles", nous devons exclure les propriétés calculées (comme ils pourraient devenir coûteux et pourraient être interprétés comme n'étant pas "actuels"):
from types import FunctionType
from inspect import getmembers
def attrs(obj):
disallowed_properties = {
name for name, value in getmembers(type(obj))
if isinstance(value, (property, FunctionType))}
return {
name: getattr(obj, name) for name in api(obj)
if name not in disallowed_properties and hasattr(obj, name)}
Et maintenant, nous ne calculons ni ne montrons la propriété, quux:
>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}
Mais nous savons peut-être que nos propriétés ne sont pas chères. Nous pouvons vouloir modifier la logique pour les inclure également. Et peut-être voulons-nous plutôt exclure d' autres descripteurs de données personnalisés .
Ensuite, nous devons personnaliser davantage cette fonction. Et il est donc logique que nous ne puissions pas avoir une fonction intégrée qui sait comme par magie exactement ce que nous voulons et la fournit. C'est une fonctionnalité dont nous avons besoin pour nous créer.
Il n'y a pas de fonction intégrée qui fait cela, et vous devez faire ce qui est le plus sémantiquement approprié à votre situation.
FunctionType
. Mais très utile - merci!
Un exemple de métaprogrammation Dump objet avec 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 Gnosis Utils :
$ 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épassé mais fonctionne toujours.
Si vous l'utilisez 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 __str__
déjà de bonnes implémentations. 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))
TypeError: vars() argument must have __dict__ attribute
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)
Production:
__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)
Ceci imprime récursivement tout le contenu de l'objet au format indenté json ou yaml:
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)
J'ai surévalué 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, 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 obtenu, et les autres réponses ici n'ont pas aidé ou la méthode semblait inutilement longue. Soit dit en passant, dans mon cas particulier, le code que j'inspectais avait un dictionnaire de dictionnaires.
Il convient de souligner qu'avec certaines classes personnalisées, vous pouvez vous retrouver avec un <someobject.ExampleClass object at 0x7f739267f400>
type de sortie inutile . Dans ce cas, vous devrez peut-être implémenter une __str__
méthode ou essayer certaines des autres solutions. J'aimerais toujours trouver quelque chose de simple qui fonctionne dans tous les scénarios, sans bibliothèques tierces.
J'avais besoin d'imprimer les informations DEBUG dans certains journaux et je n'ai pas pu utiliser pprint car cela les casserait. Au lieu de cela, j'ai fait cela et j'ai pratiquement obtenu la même chose.
DO = DemoObject()
itemDir = DO.__dict__
for i in itemDir:
print '{0} : {1}'.format(i, itemDir[i])
Pour vider "myObject":
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__ (exceptions.TypeError: l'argument 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 ou la structure de l'objet.
Je pense que json.dumps () fonctionnerait pour la plupart des objets sans le défaut = json_util.default, mais j'avais un champ datetime dans l'objet donc le sérialiseur json standard a échoué. Voir Comment surmonter "datetime.datetime non JSON sérialisable" en python?
Pourquoi pas quelque chose de simple:
for key,value in obj.__dict__.iteritems():
print key,value
for key,value in obj.__dict__.iteritems(): print key,value
?
pprint contient une «jolie imprimante» 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éteur et sont également faciles à lire pour un humain. La sortie est conservée sur une seule ligne, si possible, et indentée lorsqu'elle est divisée en plusieurs lignes.
Essayez simplement l' empreinte d'abeille .
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)
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 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 des clés ou des valeurs de types intégrés d'objets python .
Pour les attributs, qu'il s'agisse de méthodes ou de variables:
o.keys()
Pour les valeurs de ces attributs:
o.values()
Cela fonctionne quelle que soit la façon dont vos variables sont définies au sein d'une classe, à l'intérieur de __init__ ou à l'extérieur.
your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
__dict__
membre (unre.MatchObject
par exemple), mais ladir()
fonction intégrée fonctionne pour tous les objets.