print python debugging introspection pretty-print python-datamodel

python - print - ¿Existe una función incorporada para imprimir todas las propiedades y valores actuales de un objeto?



python print methods of object (22)

Entonces, lo que estoy buscando aquí es algo como la función print_r de PHP. Esto es para que pueda depurar mis scripts viendo cuál es el estado del objeto en cuestión.


¿Por qué no algo simple?

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


En la mayoría de los casos, usar __dict__ o dir() le proporcionará la información que desea. Si necesita más detalles, la biblioteca estándar incluye el módulo de inspect , que le permite obtener una cantidad impresionante de detalles. Algunos de los datos reales de información incluyen:

  • Nombres de parámetros de función y método.
  • jerarquías de clase
  • Código fuente de la implementación de una función / objetos de clase.
  • variables locales fuera de un objeto de marco

Si solo está buscando "¿qué valores de atributo tiene mi objeto?", Entonces dir() y __dict__ probablemente sean suficientes. Si realmente está buscando profundizar en el estado actual de los objetos arbitrarios (teniendo en cuenta que en Python casi todo es un objeto), entonces inspect es digno de consideración.


Esto imprime de forma recursiva todo el contenido del objeto en formato json o yaml con sangría:

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)


He subido la respuesta que menciona solo pprint. Para que quede claro, si desea ver todos los valores en una estructura de datos compleja, haga algo como:

from pprint import pprint pprint(my_var)

Donde my_var es tu variable de interés. Cuando usé pprint (vars (my_var)) no obtuve nada, y otras respuestas aquí no ayudaron o el método parecía innecesariamente largo. Por cierto, en mi caso particular, el código que estaba inspeccionando tenía un diccionario de diccionarios.

Vale la pena señalar que con algunas clases personalizadas puede terminar con un poco útil <someobject.ExampleClass object at 0x7f739267f400> tipo de salida. En ese caso, es posible que tenga que implementar un método __str__ , o probar algunas de las otras soluciones. Todavía me gustaría encontrar algo simple que funcione en todos los escenarios, sin bibliotecas de terceros.


Me gusta trabajar con objetos o values incorporados en Python.

Para los atributos independientemente de que sean métodos o variables:

o.keys()

Para los valores de esos atributos:

o.values()


Necesitaba imprimir información DEBUG en algunos registros y no pude usar pprint porque lo rompería. En su lugar hice esto y obtuve virtualmente lo mismo.

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


Para imprimir el estado actual del objeto puede:

>>> obj # in an interpreter

o

print repr(obj) # in a script

o

print obj

Para sus clases defina los métodos __str__ o __repr__ . De la documentación de Python :

__repr__(self) Llamado por la función incorporada repr() y por conversiones de cadena (comillas inversas) para calcular la representación de cadena "oficial" de un objeto. Si es posible, esto debería parecerse a una expresión de Python válida que podría usarse para recrear un objeto con el mismo valor (dado un entorno apropiado). Si esto no es posible, se debe devolver una cadena con el formato "<... alguna descripción útil ...>". El valor de retorno debe ser un objeto de cadena. Si una clase define repr () pero no __str__() , entonces __repr__() también se usa cuando se requiere una representación de cadena "informal" de instancias de esa clase. Esto se usa normalmente para la depuración, por lo que es importante que la representación sea rica en información y no sea ambigua.

__str__(self) Llamado por la función incorporada str() y por la instrucción print para calcular la representación de cadena "informal" de un objeto. Esto difiere de __repr__() en que no tiene que ser una expresión de Python válida: en su lugar se puede usar una representación más conveniente o concisa. El valor de retorno debe ser un objeto de cadena.


Para todos los que luchan con

  • vars() no devuelve todos los atributos.
  • dir() no devuelve los valores de los atributos.

El siguiente código imprime todos los atributos de obj con sus valores:

for attr in dir(obj): try: print("obj.{} = {}".format(attr, getattr(obj, attr))) except AttributeError: print("obj.{} = ?".format(attr))


Para volcar "myObject":

from bson import json_util import json print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=('','', '': '')))

Intenté vars () y dir (); Ambos fallaron por lo que estaba buscando. vars () no funcionó porque el objeto no tenía __dict__ (excepciones.TypeError: vars () el argumento debe tener el atributo __dict__). dir () no era lo que estaba buscando: es solo una lista de nombres de campos, no da los valores ni la estructura del objeto.

Creo que json.dumps () funcionaría para la mayoría de los objetos sin el valor predeterminado = json_util.default, pero tenía un campo de fecha y hora en el objeto, por lo que el serializador json estándar falló. Consulte ¿Cómo superar "datetime.datetime no JSON serializable" en python?


Podría valer la pena echarle un vistazo --

¿Hay un Python equivalente a Data :: Dumper de Perl?

Mi recomendación es esta

https://gist.github.com/1071857

Tenga en cuenta que perl tiene un módulo llamado Data :: Dumper que traduce los datos del objeto a código fuente de perl (NB: NO traduce el código a la fuente, y casi siempre no desea que el método del objeto funcione en la salida). Esto se puede usar para la persistencia, pero el propósito común es para la depuración.

Hay una serie de cosas que la impresión estándar de Python no puede lograr, en particular, solo deja de descender cuando ve una instancia de un objeto y le da el puntero hexadecimal interno del objeto (errr, ese puntero no es un uso muy común por parte de la manera). Así que, en pocas palabras, Python tiene que ver con este gran paradigma orientado a objetos, pero las herramientas que obtiene de la caja están diseñadas para trabajar con algo más que objetos.

Perl Data :: Dumper le permite controlar la profundidad a la que desea ir y también detecta estructuras enlazadas circulares (eso es realmente importante). Este proceso es fundamentalmente más fácil de lograr en Perl porque los objetos no tienen una magia particular más allá de su bendición (un proceso universalmente bien definido).


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

Salida:

__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)


Puedes probar la barra de herramientas de depuración de matraz.
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)


Puedes usar la función "dir ()" para hacer esto.

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

Otra característica útil es la ayuda.

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


Quieres vars() mezclados con pprint() :

from pprint import pprint pprint(vars(your_object))


Realmente estás mezclando dos cosas diferentes.

Use dir() , vars() o el módulo de inspect para obtener lo que le interesa (yo uso __builtins__ como ejemplo; en su lugar, puede usar cualquier objeto).

>>> l = dir(__builtins__) >>> d = __builtins__.__dict__

Imprime el diccionario como te guste:

>>> print l [''ArithmeticError'', ''AssertionError'', ''AttributeError'',...

o

>>> 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 impresión bonita también está disponible en el depurador interactivo como comando:

(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__''}


Sólo intente beeprint .

Le ayudará no solo con la impresión de variables de objetos, sino también con una salida hermosa, como esta:

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


Se ha mencionado dir , pero eso solo le dará los nombres de los atributos. Si quieres sus valores también prueba __dict__.

class O: def __init__ (self): self.value = 3 o = O()

Aquí está la salida:

>>> o.__dict__ {''value'': 3}


Si está usando esto para la depuración, y solo desea un volcado recursivo de todo, la respuesta aceptada no es satisfactoria porque requiere que sus clases ya tengan buenas implementaciones de __str__ . Si ese no es el caso, esto funciona mucho mejor:

import json print(json.dumps(YOUR_OBJECT, default=lambda obj: vars(obj), indent=1))


Un objeto de metaprogramación Dump objeto con magia :

$ 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

Sin argumentos:

$ python dump.py

<__main__.Data instance at 0x00A052D8>

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

Está un poco desactualizado pero sigue funcionando.


pprint contiene una "impresora bonita" para producir representaciones estéticamente agradables de sus estructuras de datos. El formateador produce representaciones de estructuras de datos que pueden ser analizadas correctamente por el intérprete, y también son fáciles de leer para un humano. La salida se mantiene en una sola línea, si es posible, y se sangra cuando se divide en varias líneas.


def dump(obj): for attr in dir(obj): print("obj.%s = %r" % (attr, getattr(obj, attr)))

Existen muchas funciones de terceros que agregan elementos como el manejo de excepciones, la impresión de caracteres especiales / nacionales, la repetición de objetos anidados, etc., según las preferencias de sus autores. Pero todos básicamente se reducen a esto.


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