2009-06-17 10 views
168

Sto iniziando a scrivere codice in vari progetti usando Python (incluso lo sviluppo web di Django e lo sviluppo di giochi Panda3D).Come posso guardare all'interno di un oggetto Python?

Per aiutarmi a capire cosa sta succedendo, vorrei fondamentalmente "guardare" all'interno degli oggetti Python per vedere come funzionano, come i loro metodi e proprietà.

Quindi dire che ho un oggetto Python, di cosa avrei bisogno per stampare il suo contenuto? È possibile?

risposta

46

Innanzitutto, leggere la fonte.

In secondo luogo, utilizzare la funzione dir().

+60

Vorrei invertire quell'ordine. – bayer

+4

La fonte è più informativa di dir() e una migliore abitudine a svilupparsi. –

+11

Mi permetto di dissentire. dir() è molto più veloce e nel 99% dei casi scopriamo cosa vi serve in combinazione con help(). – bayer

6

È possibile elencare gli attributi di un oggetto con dir() nella shell:

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

Naturalmente, c'è anche la ispezionare modulo: 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

Funziona perfettamente con Python 3 se si aggiungono solo paren- ti alle stampe. – ConstantineK

212

Python ha un insieme forte delle caratteristiche di introspezione.

Date un'occhiata al seguente built-in functions:

type() e dir() sono particolarmente utili per il controllo del tipo di un oggetto e il suo insieme di attributi, rispettivamente.

+13

Non sapevo che il termine fosse "introspezione". È un grande aiuto! Come tutte le funzioni che mi hai dato ... Grazie! La proprietà – littlejim84

+2

, classmethod e staticmethod non sono correlate all'introspezione. Questi metodi creano tutti tipi speciali di oggetti che possono essere usati per definire classi con un comportamento speciale, ma non aiutano a controllare quelle classi o costrutti. – SingleNegationElimination

+0

La risposta di @Brian qui sotto mostra come anche visualizzare il codice sorgente di vari oggetti python all'interno di python. Questo è quello che cercavo inizialmente e sono sicuro che non sarò solo. (Potrebbe valere la pena includere un riferimento alla sua risposta in questa risposta poiché è la più accettata.) – michaelavila

0

Inoltre, se si vuole guardare la lista e dizionari dentro, è possibile utilizzare pprint()

2

pprint e dir insieme grande lavoro

4

Se si desidera guardare i parametri e metodi, come altri hanno fatto fuori si può ben utilizzare pprint o dir()

Se volete vedere il valore reale dei contenuti, si può fare

object.__dict__

17

Se questo è per l'esplorazione per vedere cosa sta succedendo, mi consiglia di guardare IPython. Questo aggiunge varie scorciatoie per ottenere una documentazione di oggetti, proprietà e persino il codice sorgente. Ad esempio, aggiungendo un "?" a una funzione verrà fornito l'aiuto per l'oggetto (in pratica una scorciatoia per "help (obj)", dove usando due? ("func??") verrà visualizzato il codice sorgente se disponibile.

Ci sono anche molte altre comodità, come il completamento delle schede, la bella stampa dei risultati, la cronologia dei risultati ecc. Che lo rendono molto utile per questo tipo di programmazione esplorativa.

Per ulteriori uso programmatico di introspezione, i comandi incorporati di base come dir(), vars(), getattr ecc saranno utili, ma vale la pena il vostro tempo per verificare il modulo inspect. Per recuperare la fonte di una funzione, usare "inspect.getsource", ad esempio, applicandolo a se stesso:

>>> 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 è anche spesso utile se hai a che fare con lo spostamento o manipolazione di funzioni, in quanto darà i nomi e di default valori dei parametri di funzione.

136

object.__dict__

+2

Non funziona con gli slot –

+0

questo non funziona. – Sajuuk

+0

Funziona per me (Python 3.6.2). – OmarOthman

6

Altri hanno già menzionato la dir() built-in che suona come quello che stai cercando, ma ecco un altro buon consiglio. Molte librerie, inclusa la maggior parte della libreria standard, sono distribuite in forma sorgente. Significa che puoi facilmente leggere il codice sorgente direttamente. Il trucco sta nel trovarlo; per esempio:

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

Il file * .pyc viene compilato, in modo da rimuovere il trailing 'c' e aprire il file non compilato * .py nel vostro editor preferito o il file viewer:

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

I Lo ho trovato incredibilmente utile per scoprire cose come le eccezioni sollevate da una determinata API. Questo tipo di dettaglio è raramente ben documentato nel mondo Python.

40

Sono sorpreso che nessuno abbia ancora menzionato l'aiuto!

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

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

foo() 
    foo! 

Guida consente di leggere la docstring e avere un'idea di quali attributi può avere una classe, che è piuttosto utile.

+2

Cosa succede se il metodo non ha docstring, cioè nessuna documentazione? – Sajuuk

1

Se si desidera guardare all'interno di un oggetto live, il modulo inspect di python è una buona risposta. In generale, funziona per ottenere il codice sorgente delle funzioni che sono definite in un file sorgente da qualche parte sul disco. Se si desidera ottenere l'origine delle funzioni live e dei lambda definiti nell'interprete, è possibile utilizzare dill.source.getsource da dill. Può anche ottenere il codice per i metodi e le funzioni delle classi legate o non definite definite in curry ... tuttavia, potresti non essere in grado di compilare quel codice senza il codice dell'oggetto che lo contiene.

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

C'è un codice Python Library costruire solo per questo scopo: inspect Introdotto in Python 2.7

10

Se siete interessati a una GUI per questo, dare un'occhiata a objbrowser. Usa il modulo inspect dalla libreria standard di Python per l'introspezione degli oggetti sottostanti.

objbrowserscreenshot

6

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

uscita:

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

Due grandi strumenti per l'ispezione del codice sono:

  1. IPython. Un terminale Python che consente di ispezionare utilizzando il completamento della scheda.

  2. Eclipse con il PyDev plugin. Ha un debugger eccellente che ti permette di rompere in un determinato punto e ispezionare oggetti sfogliando tutte le variabili come un albero. È anche possibile utilizzare il terminale integrato per provare il codice in quel punto o digitare l'oggetto e premere "." per avere suggerimenti sul codice per te.

enter image description here

0

Vars (obj) restituisce gli attributi di un oggetto.

Problemi correlati