2009-06-17 8 views
168

Estoy empezando a codificar en varios proyectos utilizando Python (incluido el desarrollo web de Django y el desarrollo de juegos Panda3D).¿Cómo miro dentro de un objeto de Python?

Para ayudarme a entender lo que está pasando, me gustaría básicamente 'mirar' dentro de los objetos de Python para ver cómo marcan, como sus métodos y propiedades.

Digamos que tengo un objeto Python, ¿qué necesitaría para imprimir su contenido? ¿Es eso posible?

Respuesta

46

Primero, lea la fuente.

En segundo lugar, utilice la función dir().

+60

Invertiría esa orden. – bayer

+4

La fuente es más informativa que dir() y un mejor hábito para desarrollar. –

+11

Me gustaría diferir. dir() es mucho más rápido y en el 99% de los casos descubrimos lo que necesitas junto con la ayuda(). – bayer

6

Se pueden listar los atributos de un objeto con dir() en la cáscara:

>>> dir(object()) 
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 

Por supuesto, también existe la inspeccione módulo: http://docs.python.org/library/inspect.html#module-inspect

7
"""Visit http://diveintopython.net/""" 

__author__ = "Mark Pilgrim ([email protected])" 


def info(object, spacing=10, collapse=1): 
    """Print methods and doc strings. 

    Takes module, class, list, dictionary, or string.""" 
    methodList = [e for e in dir(object) if callable(getattr(object, e))] 
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) 
    print "\n".join(["%s %s" % 
        (method.ljust(spacing), 
         processFunc(str(getattr(object, method).__doc__))) 
        for method in methodList]) 

if __name__ == "__main__": 
    print help.__doc__ 
+3

Esto funciona bien en python 3 si solo agrega parens alrededor de las impresiones. – ConstantineK

212

Python tiene un conjunto fuerte de características de introspección.

Tome un vistazo a la siguiente built-in functions:

type() y dir() son particularmente útiles para la inspección del tipo de un objeto y su conjunto de atributos, respectivamente.

+13

No sabía que el término era 'introspección'. ¡Es una gran ayuda! Además de todos los funcionamientos que me has dado ... ¡Gracias! – littlejim84

+2

propiedad, classmethod y staticmethod no están relacionados con la introspección. Todos estos métodos crean tipos especiales de objetos que se pueden usar para definir clases con un comportamiento especial, pero no ayudan a inspeccionar esas clases o construcciones. – SingleNegationElimination

+0

La respuesta de @Brian a continuación le muestra cómo ver también el código fuente de varios objetos python desde dentro de python. Eso es lo que estaba buscando originalmente y estoy seguro de que no estaré solo. (Puede valer la pena incluir una referencia a su respuesta en esta respuesta, ya que es la más aceptada). – michaelavila

0

Además, si desea ver la lista de diccionarios en el interior, puede utilizar pprint()

2

pprint y dir juntos un gran trabajo

4

Si desea buscar en los parámetros y métodos, como otros han señalado salir bien puede utilizar pprint o dir()

Si usted quiere ver el valor real de los contenidos, que puede hacer

object.__dict__

17

Si esto es para explorar para ver qué está pasando, recomendaría mirar IPython. Esto agrega varios accesos directos para obtener una documentación de objetos, propiedades e incluso código fuente. Por ejemplo, agregar un "?" a una función dará la ayuda para el objeto (de hecho, un atajo para "ayuda (obj)", mientras que usando dos? s ("func??") mostrará el código fuente si está disponible.

También hay una gran cantidad de comodidades adicionales, como la finalización de pestañas, impresión bonita de resultados, historial de resultados, etc. que lo hacen muy útil para este tipo de programación exploratoria.

Para un uso más programático de la introspección, las órdenes internas básicas como dir(), vars(), etc getattr serán útiles, pero es bien digno de su tiempo a la salida del módulo inspect. Para buscar el origen de una función, utilice "inspect.getsource", por ejemplo, aplicándolo a sí mismo:

>>> print inspect.getsource(inspect.getsource) 
def getsource(object): 
    """Return the text of the source code for an object. 

    The argument may be a module, class, method, function, traceback, frame, 
    or code object. The source code is returned as a single string. An 
    IOError is raised if the source code cannot be retrieved.""" 
    lines, lnum = getsourcelines(object) 
    return string.join(lines, '') 

inspect.getargspec también es con frecuencia útil si usted está tratando con envoltura o la manipulación de funciones, ya que le dará los nombres y por defecto valores de los parámetros de la función.

136

object.__dict__

+2

No funciona con las ranuras –

+0

esto no está funcionando. – Sajuuk

+0

Funciona para mí (Python 3.6.2). – OmarOthman

6

Otros ya han mencionado el dir() incorporada que suena como lo que estás buscando, pero aquí hay otro buen consejo. Muchas bibliotecas, incluida la mayoría de la biblioteca estándar, se distribuyen en forma de fuente. Lo que significa que puedes leer fácilmente el código fuente directamente. El truco está en encontrarlo; por ejemplo:

>>> import string 
>>> string.__file__ 
'/usr/lib/python2.5/string.pyc' 

El archivo * .pyc se compila, por lo retire el terminador 'c' y abrir el archivo sin compilar * .py en su editor o visor de archivos favorito:

/usr/lib/python2.5/string.py 

I He encontrado esto increíblemente útil para descubrir cosas como qué excepciones se plantean desde una API determinada. Este tipo de detalles rara vez está bien documentado en el mundo de Python.

40

¡Estoy sorprendido de que nadie haya mencionado la ayuda todavía!

In [1]: def foo(): 
    ...:  "foo!" 
    ...: 

In [2]: help(foo) 
Help on function foo in module __main__: 

foo() 
    foo! 

Help le permite leer el docstring y tener una idea de los atributos que una clase puede tener, lo cual es bastante útil.

+2

¿Qué sucede si el método no tiene docstring, es decir, no hay documentación? – Sajuuk

1

Si desea mirar dentro de un objeto en vivo, entonces el módulo inspect de python es una buena respuesta. En general, funciona para obtener el código fuente de las funciones que se definen en un archivo fuente en algún lugar del disco. Si desea obtener el origen de las funciones en vivo y las lambdas que se definieron en el intérprete, puede usar dill.source.getsource desde dill. También puede obtener el código de métodos y funciones de clase enlazados o no definidos definidos en curries ... sin embargo, es posible que no pueda compilar ese código sin el código del objeto adjunto.

>>> from dill.source import getsource 
>>> 
>>> def add(x,y): 
... return x+y 
... 
>>> squared = lambda x:x**2 
>>> 
>>> print getsource(add) 
def add(x,y): 
    return x+y 

>>> print getsource(squared) 
squared = lambda x:x**2 

>>> 
>>> class Foo(object): 
... def bar(self, x): 
...  return x*x+x 
... 
>>> f = Foo() 
>>> 
>>> print getsource(f.bar) 
def bar(self, x): 
    return x*x+x 

>>> 
2

Hay una biblioteca construir código Python para este fin: inspect Introducido en Python 2.7

10

Si usted está interesado en una interfaz gráfica de usuario para esto, echar un vistazo a objbrowser. Utiliza el módulo de inspección de la biblioteca estándar de Python para la introspección del objeto debajo.

objbrowserscreenshot

6

Trate 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(), indent=' ', depth=2, width=30, seq_length=6, 
       show_protected=True, show_private=False, show_static=True, 
       show_properties=True, show_address=True) 

Salida:

__main__.A at 0x1debd68L (
    _p = 8, 
    foo = [0, 1, 2, ..., 7, 8, 9], 
    s = 5 
) 
3

dos grandes herramientas para la inspección de código son:

  1. IPython. Un terminal python que le permite inspeccionar usando la terminación de pestañas.

  2. Eclipse con PyDev plugin. Tiene un depurador excelente que le permite dividirse en un punto determinado e inspeccionar objetos explorando todas las variables como un árbol. Incluso puede usar la terminal incorporada para probar el código en ese punto o escribir el objeto y presionar '.' para darle sugerencias de código para usted.

enter image description here

0

vars (Obj) devuelve los atributos de un objeto.

Cuestiones relacionadas