Domanda

Quindi quello che sto cercando qui è qualcosa come la print_r di PHP. Questo è così che posso eseguire il debug dei miei script vedendo qual è lo stato dell'oggetto in questione.

È stato utile?

Soluzione

Stai davvero mescolando insieme due cose diverse.

Usa dir() , vars() o inspect per ottenere ciò che ti interessa (io uso __builtins__ come esempio; puoi invece usare qualsiasi oggetto).

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

Stampa quel dizionario come preferisci:

>>> 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 stampa graziosa è disponibile anche nel debugger interattivo come 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__'}

Altri suggerimenti

Desideri vars() mescolato con pprint():

from pprint import pprint
pprint(vars(your_object))
def dump(obj):
  for attr in dir(obj):
    print("obj.%s = %r" % (attr, getattr(obj, attr)))

Esistono molte funzioni di terze parti che aggiungono cose come la gestione delle eccezioni, la stampa di caratteri nazionali / speciali, il ricorrere in oggetti nidificati ecc. in base alle preferenze dei loro autori. Ma sostanzialmente si riducono a questo.

dir è stato menzionato, ma questo ti darà solo i nomi degli attributi. Se vuoi anche i loro valori, prova __dict__.

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

o = O()

Ecco l'output:

>>> o.__dict__

{'value': 3}

Per stampare lo stato corrente dell'oggetto potresti:

>>> obj # in an interpreter

o

print repr(obj) # in a script

o

print obj

Per le tue classi definisci i metodi __str__ o __repr__. Dalla Documentazione Python :

  

__repr__(self) Chiamato dalla funzione integrata repr() e dalla stringa   conversioni (virgolette inverse) in   calcola il " ufficiale " stringa   rappresentazione di un oggetto. Per niente   possibile, questo dovrebbe apparire come a   espressione Python valida che potrebbe essere   usato per ricreare un oggetto con il   stesso valore (dato un appropriato   ambiente). Se ciò non è possibile,   una stringa della forma " < ... alcune utili   Descrizione ... gt &; " dovrebbe essere restituito.   Il valore restituito deve essere una stringa   oggetto. Se una classe definisce repr ()   ma non __str__(), quindi __repr__() lo è   utilizzato anche quando un " informale " stringa   rappresentazione di esempi di ciò   classe è richiesta. Questo è in genere   utilizzato per il debug, quindi è importante   che la rappresentazione è   ricco di informazioni e inequivocabile.

     

__str__(self) Chiamato dalla funzione integrata str() e dalla stampa   istruzione per calcolare il " informale "   rappresentazione in stringa di un oggetto.   Ciò differisce da <=> in questo   non deve essere un Python valido   espressione: un più conveniente o   rappresentazione concisa può essere utilizzata   anziché. Il valore restituito deve essere a   oggetto stringa.

Puoi usare " dir () " funzione per fare questo.

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

Un'altra utile funzione è la guida.

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

Potrebbe valere la pena dare un'occhiata -

Esiste un Python equivalente ai dati di Perl :: Dumper?

La mia raccomandazione è questa -

https://gist.github.com/1071857

Nota che perl ha un modulo chiamato Data :: Dumper che traduce i dati degli oggetti in codice sorgente perl (NB: NON traduce il codice in sorgente, e quasi sempre non vuoi che le funzioni del metodo oggetto nel produzione). Questo può essere usato per la persistenza, ma lo scopo comune è il debug.

Ci sono una serie di cose che la pprint python standard non riesce a raggiungere, in particolare smette di scendere quando vede un'istanza di un oggetto e ti dà il puntatore esadecimale interno dell'oggetto (errr, quel puntatore non è molto di utilizzo a proposito). Quindi, in poche parole, Python è incentrato su questo fantastico paradigma orientato agli oggetti, ma gli strumenti che ottieni fuori dalla scatola sono progettati per lavorare con qualcosa di diverso dagli oggetti.

Il perl Data :: Dumper ti consente di controllare quanto in profondità vuoi andare, e rileva anche strutture collegate circolari (questo è davvero importante). Questo processo è fondamentalmente più facile da realizzare in perl perché gli oggetti non hanno una magia particolare oltre la loro benedizione (un processo universalmente ben definito).

Nella maggior parte dei casi, l'utilizzo di __dict__ o dir() ti fornirà le informazioni che desideri. Se dovessi avere bisogno di maggiori dettagli, la libreria standard include il modulo inspect , che ti consente di ottenere una quantità impressionante di dettagli. Alcuni dei veri nuggest di informazioni includono:

  • nomi dei parametri di funzione e metodo
  • gerarchie di classi
  • codice sorgente dell'implementazione di un oggetto funzioni / classe
  • variabili locali fuori da un oggetto frame

Se stai solo cercando " quali valori di attributo ha il mio oggetto? " ;, allora inspect e <=> sono probabilmente sufficienti. Se stai davvero cercando di scavare nello stato attuale di oggetti arbitrari (tenendo presente che in Python quasi tutto è un oggetto), allora <=> è degno di considerazione.

Un esempio di metaprogrammazione Dump object with magic :

$ 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

Senza argomenti:

$ python dump.py
<__main__.Data instance at 0x00A052D8>

Con Utilità Gnosis :

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

È un po 'obsoleto ma funziona ancora.

Se lo stai usando per il debug e vuoi solo un dump ricorsivo di tutto, la risposta accettata non è soddisfacente perché richiede che le tue classi abbiano già buone __str__ implementazioni. In caso contrario, funziona molto meglio:

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

Stampa in modo ricorsivo tutto il contenuto dell'oggetto in formato rientrato json o 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)

Consiglio di usare 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__.

Avevo bisogno di stampare le informazioni di DEBUG in alcuni registri e non ero in grado di usare pprint perché si sarebbe rotto. Invece l'ho fatto e ho praticamente ottenuto la stessa cosa.

DO = DemoObject()

itemDir = DO.__dict__

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

Per scaricare " myObject " ;:

from bson import json_util
import json

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

Ho provato vars () e dir (); entrambi hanno fallito per quello che stavo cercando. vars () non ha funzionato perché l'oggetto non aveva __dict__ (exceptions.TypeError: l'argomento vars () deve avere l'attributo __dict__). dir () non era quello che stavo cercando: è solo un elenco di nomi di campi, non fornisce i valori o la struttura dell'oggetto.

Penso che json.dumps () funzionerebbe per la maggior parte degli oggetti senza default = json_util.default, ma avevo un campo datetime nell'oggetto, quindi il serializzatore json standard non è riuscito. Vedi Come superare & Quot; datetime.datetime quot & non serializzabile JSON; in pitone?

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

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(), show_protected=True, show_static=True, show_properties=True)

Output:

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

pprint contiene un & # 8220; bella stampante < !> # 8221; per produrre rappresentazioni esteticamente gradevoli delle tue strutture dati. Il formatter produce rappresentazioni di strutture dati che possono essere analizzate correttamente dall'interprete e sono anche facili da leggere per un essere umano. L'output viene mantenuto su una sola riga, se possibile, e indentato quando suddiviso su più righe.

Perché non qualcosa di semplice:

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

Ho annullato la risposta che menziona solo la pprint. Per essere chiari, se vuoi vedere tutti i valori in una struttura di dati complessa, fai qualcosa del tipo:

from pprint import pprint
pprint(my_var)

Dove my_var è la tua variabile di interesse. Quando ho usato pprint (vars (my_var)) non ho ottenuto nulla e altre risposte qui non sono state di aiuto o il metodo sembrava inutilmente lungo. A proposito, nel mio caso particolare, il codice che stavo ispezionando aveva un dizionario di dizionari.

Vale la pena sottolineare che con alcune classi personalizzate potresti semplicemente ottenere un tipo di output <someobject.ExampleClass object at 0x7f739267f400> non utile. In tal caso, potrebbe essere necessario implementare un metodo __str__ o provare alcune delle altre soluzioni. Mi piacerebbe ancora trovare qualcosa di semplice che funzioni in tutti gli scenari, senza librerie di terze parti.

Prova beeprint .

Ti aiuterà non solo nella stampa delle variabili degli oggetti, ma anche in un bellissimo output, come questo:

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

Per tutti coloro che lottano con

  • vars() non restituisce tutti gli attributi.
  • dir() non restituisce i valori degli attributi.

Il codice seguente stampa tutti gli attributi di obj con i loro valori:

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

Puoi provare Flask Debug Toolbar.
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)

Mi piace lavorare con tipi predefiniti di oggetti Python chiavi o valori .

Per gli attributi indipendentemente dal fatto che siano metodi o variabili:

o.keys()

Per i valori di tali attributi:

o.values()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top