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


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


683
2017-10-10 16:19


origen


Respuestas:


Realmente estás mezclando dos cosas diferentes.

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

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

Imprime ese diccionario por más elegante que 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 un 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__'}

418
2017-10-10 17:27



Usted quiere vars() mezclado con pprint():

from pprint import pprint
pprint(vars(your_object))

729
2017-10-11 01:16



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

Hay muchas funciones de terceros que agregan cosas como manejo de excepciones, impresión de caracteres nacionales / especiales, recurrencia en objetos anidados, etc. según las preferencias de los autores. Pero todos básicamente se reducen a esto.


139
2017-10-10 16:36



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

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

o = O()

Aquí está el resultado:

>>> o.__dict__

{'value': 3}

35
2017-10-10 16:44



Para imprimir el estado actual del objeto, puede:

>>> obj # in an interpreter

o

print repr(obj) # in a script

o

print obj

Para tus clases define __str__ o __repr__ métodos. Desde el Documentación de Python:

__repr__(self) Llamado por el repr() función incorporada y por cadena   conversiones (cotizaciones inversas) a   calcular la cadena "oficial"   representación de un objeto. Como mucho   posible, esto debería verse como un   expresión válida de Python que podría ser   utilizado para recrear un objeto con el   mismo valor (dado un apropiado   ambiente). Si esto no es posible,   una cadena de la forma "<... alguna útil   descripción ...> "debe ser devuelto.   El valor de retorno debe ser una cadena   objeto. Si una clase define repr()   pero no __str__(), entonces __repr__() es   también se usa cuando una cadena "informal"   representación de instancias de ese   clase es requerida Esto es típicamente   utilizado para la depuración, por lo que es importante   que la representación es   rica en información y no ambigua.

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


19
2017-10-11 07:29



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

17
2017-10-10 16:20



Podría valer la pena echarle un vistazo --

¿Existe 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 perl (NB: NO convierte el código de nuevo en fuente, y casi siempre no quiere las funciones del método objeto en la salida). Esto se puede usar para la persistencia, pero el propósito común es la depuración.

Hay una serie de cosas que python pprint no logra, en particular, simplemente deja de descender cuando ve una instancia de un objeto y le da el puntero hexagonal interno del objeto (errr, ese puntero no es muy utilizado por la manera). Entonces, en pocas palabras, Python tiene que ver con este gran paradigma orientado a objetos, pero las herramientas que obtienes de la caja están diseñadas para trabajar con algo que no sean objetos.

Perl Data :: Dumper le permite controlar qué tan profundo desea ir, y también detecta estructuras circulares vinculadas (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).


12
2017-11-15 04:11



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

  • nombres de función y parámetros del método
  • jerarquías de clase
  • código fuente de la implementación de un objeto de funciones / 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 buscas 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.


9
2017-10-15 14:53



Un ejemplo de metaprogramación Volcar 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.


7
2017-10-11 07:53