Antworten:
Sie mischen wirklich zwei verschiedene Dinge zusammen.
Verwendung dir()
, vars()
oder das inspect
Modul zu bekommen , was Sie interessiert sind (ich verwende __builtins__
als Beispiel, Sie ein beliebiges Objekt verwenden können , statt).
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__
Drucken Sie das Wörterbuch nach Belieben aus:
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...
oder
>>> 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',
...
Hübsches Drucken ist auch im interaktiven Debugger als Befehl verfügbar:
(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__'}
print re.compile(r'slots').search('No slots here either.').__slots__
inspect
in deiner Antwort nicht mehr über das Modul? Ich denke, es ist am nächsten an print_r oder var_dump.
dir()
? dir()
Gibt nur eine Liste von Namen zurück, und nicht alle sind im vars()
oder im __dict__
Attribut vorhanden.
Sie möchten vars()
gemischt mit pprint()
:
from pprint import pprint
pprint(vars(your_object))
vars()
Gibt einfach das __dict__
Argument zurück und das ist auch der Fallback für den dir()
Fall, dass es keine __dir__
Methode gibt. also dir()
erstmal verwenden, wie gesagt.
dir()
gibt dir alle eingebauten Dinge, die dir wahrscheinlich egal sind, wie __str__
und __new__
. var()
nicht.
__dict__
Attribut haben.
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
Es gibt viele Funktionen von Drittanbietern, die Dinge wie Ausnahmebehandlung, Drucken von nationalen / Sonderzeichen, Rekursion in verschachtelte Objekte usw. gemäß den Präferenzen ihrer Autoren hinzufügen. Aber sie alle laufen im Grunde darauf hinaus.
getmembers()
Funktion im Standardmodul verwenden inspect
, aber ich dachte, dies wäre nützlicher, da es zeigt, wie Introspektion im Allgemeinen durchgeführt wird.
__dict__
(wie __doc__
und __module__
) nicht gefunden werden . Funktioniert außerdem __dict__
überhaupt nicht für Objekte, mit denen deklariert wurde __slots__
. __dict__
Zeigt im Allgemeinen Eigenschaften auf Benutzerebene an, die tatsächlich intern in einem Wörterbuch gespeichert sind. dir () zeigt mehr.
__dict__
Attribut / Mitglied. Ich weiß, dass es verrückt ist, aber wahr. Eingebaute wie int
und str
oder re.MatchObject
sind gängige Beispiele. Versuchen Sie 'hello'.__dict__
, dann versuchen Siedir('hello')
dir wurde erwähnt, aber das gibt dir nur die Namen der Attribute. Wenn Sie auch deren Werte möchten, versuchen Sie __dict__.
class O:
def __init__ (self):
self.value = 3
o = O()
Hier ist die Ausgabe:
>>> o.__dict__
{'value': 3}
set
haben nicht __dict__
, so für sie wird es mitAttributeError: 'set' object has no attribute '__dict__'
Sie können dazu die Funktion "dir ()" verwenden.
>>> 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']
>>>
Eine weitere nützliche Funktion ist die Hilfe.
>>> 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
So drucken Sie den aktuellen Status des Objekts:
>>> obj # in an interpreter
oder
print repr(obj) # in a script
oder
print obj
Für Ihre Klassen definieren __str__
oder __repr__
Methoden. Aus der Python-Dokumentation :
__repr__(self)
Wird von derrepr()
integrierten Funktion und von Zeichenfolgenkonvertierungen (umgekehrte Anführungszeichen) aufgerufen , um die "offizielle" Zeichenfolgendarstellung eines Objekts zu berechnen. Wenn möglich, sollte dies wie ein gültiger Python-Ausdruck aussehen, mit dem ein Objekt mit demselben Wert (in einer geeigneten Umgebung) neu erstellt werden kann. Ist dies nicht möglich, sollte eine Zeichenfolge der Form "<... eine nützliche Beschreibung ...>" zurückgegeben werden. Der Rückgabewert muss ein Zeichenfolgenobjekt sein. Wenn eine Klasse repr () definiert, aber nicht__str__()
,__repr__()
wird sie auch verwendet, wenn eine "informelle" Zeichenfolgendarstellung von Instanzen dieser Klasse erforderlich ist. Dies wird normalerweise zum Debuggen verwendet. Daher ist es wichtig, dass die Darstellung reich an Informationen und eindeutig ist.
__str__(self)
Wird von derstr()
integrierten Funktion und von der print-Anweisung aufgerufen , um die "informelle" Zeichenfolgendarstellung eines Objekts zu berechnen. Dies unterscheidet sich davon,__repr__()
dass es sich nicht um einen gültigen Python-Ausdruck handeln muss: Stattdessen kann eine bequemere oder präzisere Darstellung verwendet werden. Der Rückgabewert muss ein Zeichenfolgenobjekt sein.
print "DEBUG: object value: " + repr(obj)
Könnte einen Besuch wert sein -
Gibt es ein Python-Äquivalent zu Perls Data :: Dumper?
Meine Empfehlung lautet:
https://gist.github.com/1071857
Beachten Sie, dass Perl über ein Modul namens Data :: Dumper verfügt, das Objektdaten zurück in den Perl-Quellcode übersetzt (Hinweis: Code wird NICHT zurück in den Quellcode übersetzt, und fast immer möchten Sie die Funktionen der Objektmethode in der Ausgabe nicht verwenden). Dies kann für die Persistenz verwendet werden, aber der allgemeine Zweck ist das Debuggen.
Es gibt eine Reihe von Dingen, die mit Standard-Python-Drucken nicht erreicht werden können. Insbesondere hört es einfach auf abzusteigen, wenn es eine Instanz eines Objekts sieht, und gibt Ihnen den internen Hex-Zeiger des Objekts (ähm, dieser Zeiger wird von nicht viel verwendet der Weg). Kurz gesagt, bei Python dreht sich alles um dieses großartige objektorientierte Paradigma, aber die Tools, die Sie sofort erhalten, sind für die Arbeit mit etwas anderem als Objekten konzipiert.
Mit dem Perl Data :: Dumper können Sie steuern, wie tief Sie gehen möchten, und auch kreisförmig verknüpfte Strukturen erkennen (das ist wirklich wichtig). Dieser Prozess ist in Perl grundsätzlich einfacher zu erreichen, da Objekte über ihren Segen hinaus keine besondere Magie haben (ein allgemein gut definierter Prozess).
Ich empfehle die Verwendung 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__.
In den meisten Fällen erhalten Sie mit __dict__
oder dir()
erhalten Sie die gewünschten Informationen. Sollten Sie weitere Details benötigen, enthält die Standardbibliothek das Inspect- Modul, mit dem Sie beeindruckende Details erhalten. Einige der wirklich wichtigsten Informationen sind:
Wenn Sie gerade auf der Suche nach „welchen Attributwert hat mein Objekt?“, Dann dir()
und __dict__
ist wahrscheinlich ausreichend. Wenn Sie wirklich in den aktuellen Zustand beliebiger Objekte eintauchen möchten (denken Sie daran, dass in Python fast alles ein Objekt ist), dann inspect
ist dies eine Überlegung wert.
Gibt es eine integrierte Funktion zum Drucken aller aktuellen Eigenschaften und Werte eines Objekts?
Nein. Die am besten bewertete Antwort schließt einige Arten von Attributen aus, und die akzeptierte Antwort zeigt, wie alle Attribute abgerufen werden, einschließlich Methoden und Teile der nicht öffentlichen API. Dafür gibt es aber keine gute vollständige eingebaute Funktion.
Die kurze Konsequenz ist also, dass Sie Ihre eigenen schreiben können, aber es werden Eigenschaften und andere berechnete Datenbeschreibungen berechnet, die Teil der öffentlichen API sind, und das möchten Sie möglicherweise nicht:
from pprint import pprint
from inspect import getmembers
from types import FunctionType
def attributes(obj):
disallowed_names = {
name for name, value in getmembers(type(obj))
if isinstance(value, FunctionType)}
return {
name: getattr(obj, name) for name in dir(obj)
if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
def print_attributes(obj):
pprint(attributes(obj))
Beachten Sie die Anwendung der aktuell am besten bewerteten Antwort auf eine Klasse mit vielen verschiedenen Arten von Datenelementen:
from pprint import pprint
class Obj:
__slots__ = 'foo', 'bar', '__dict__'
def __init__(self, baz):
self.foo = ''
self.bar = 0
self.baz = baz
@property
def quux(self):
return self.foo * self.bar
obj = Obj('baz')
pprint(vars(obj))
druckt nur:
{'baz': 'baz'}
Da vars
nur das __dict__
Objekt zurückgegeben wird und es sich nicht um eine Kopie handelt. Wenn Sie also das von vars zurückgegebene Diktat ändern, ändern Sie auch __dict__
das Objekt selbst.
vars(obj)['quux'] = 'WHAT?!'
vars(obj)
kehrt zurück:
{'baz': 'baz', 'quux': 'WHAT?!'}
- was schlecht ist, weil quux eine Eigenschaft ist, die wir nicht festlegen sollten und die nicht im Namespace sein sollte ...
Das Anwenden der Ratschläge in der aktuell akzeptierten Antwort (und anderen) ist nicht viel besser:
>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar', 'baz', 'foo', 'quux']
Wie wir sehen können, werden dir
nur alle (eigentlich nur die meisten) Namen zurückgegeben, die einem Objekt zugeordnet sind.
inspect.getmembers
, in den Kommentaren erwähnt, ist ähnlich fehlerhaft - es gibt alle Namen und Werte zurück.
Während des Unterrichts lassen meine Schüler eine Funktion erstellen, die die semantisch öffentliche API eines Objekts bereitstellt:
def api(obj):
return [name for name in dir(obj) if name[0] != '_']
Wir können dies erweitern, um eine Kopie des semantischen Namespace eines Objekts bereitzustellen , aber wir müssen ausschließen __slots__
, die nicht zugewiesen sind, und wenn wir die Anforderung nach "aktuellen Eigenschaften" ernst nehmen, müssen wir berechnete Eigenschaften ausschließen (as Sie könnten teuer werden und als nicht "aktuell" interpretiert werden.
from types import FunctionType
from inspect import getmembers
def attrs(obj):
disallowed_properties = {
name for name, value in getmembers(type(obj))
if isinstance(value, (property, FunctionType))}
return {
name: getattr(obj, name) for name in api(obj)
if name not in disallowed_properties and hasattr(obj, name)}
Und jetzt berechnen oder zeigen wir die Eigenschaft nicht, quux:
>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}
Aber vielleicht wissen wir, dass unsere Immobilien nicht teuer sind. Möglicherweise möchten wir die Logik ändern, um sie auch einzuschließen. Und vielleicht möchten wir stattdessen andere benutzerdefinierte Datenbeschreibungen ausschließen .
Dann müssen wir diese Funktion weiter anpassen. Daher ist es sinnvoll, dass wir keine integrierte Funktion haben können, die auf magische Weise genau weiß, was wir wollen, und diese bereitstellt. Dies ist eine Funktionalität, die wir selbst erstellen müssen.
Es gibt keine eingebaute Funktion, die dies tut, und Sie sollten das tun, was für Ihre Situation semantisch am besten geeignet ist.
FunctionType
. Aber sehr hilfreich - danke!
Ein Metaprogrammierungsbeispiel Objekt mit Magie entsorgen :
$ 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
Ohne Argumente:
$ python dump.py
<__main__.Data instance at 0x00A052D8>
Mit 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>
Es ist etwas veraltet, funktioniert aber immer noch.
Wenn Sie dies zum Debuggen verwenden und nur einen rekursiven Speicherauszug von allem wünschen, ist die akzeptierte Antwort unbefriedigend, da Ihre Klassen bereits über gute __str__
Implementierungen verfügen müssen . Wenn dies nicht der Fall ist, funktioniert dies viel besser:
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
TypeError: vars() argument must have __dict__ attribute
Versuchen Sie es mit 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)
Ausgabe:
__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)
Dadurch werden alle Objektinhalte rekursiv im json- oder yaml-eingerückten Format ausgedruckt:
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)
Ich habe die Antwort, die nur Drucke erwähnt, positiv bewertet. Wenn Sie alle Werte in einer komplexen Datenstruktur anzeigen möchten , gehen Sie wie folgt vor:
from pprint import pprint
pprint(my_var)
Wobei my_var Ihre interessierende Variable ist. Als ich benutzte, pprint(vars(my_var))
bekam ich nichts und andere Antworten hier halfen nicht oder die Methode sah unnötig lang aus. Übrigens hatte der Code, den ich inspizierte, in meinem speziellen Fall ein Wörterbuch mit Wörterbüchern.
Es ist erwähnenswert, dass bei einigen benutzerdefinierten Klassen möglicherweise nur eine nicht hilfreiche <someobject.ExampleClass object at 0x7f739267f400>
Ausgabe erfolgt. In diesem Fall müssen Sie möglicherweise eine __str__
Methode implementieren oder einige der anderen Lösungen ausprobieren. Ich möchte immer noch etwas Einfaches finden, das in allen Szenarien funktioniert, ohne Bibliotheken von Drittanbietern.
Ich musste DEBUG-Informationen in einigen Protokollen drucken und konnte pprint nicht verwenden, da dies zu einer Unterbrechung führen würde. Stattdessen habe ich das gemacht und praktisch das Gleiche bekommen.
DO = DemoObject()
itemDir = DO.__dict__
for i in itemDir:
print '{0} : {1}'.format(i, itemDir[i])
So löschen Sie "myObject":
from bson import json_util
import json
print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))
Ich habe vars () und dir () ausprobiert. beide scheiterten an dem, wonach ich suchte. vars () hat nicht funktioniert, weil das Objekt kein __dict__ hatte (Ausnahmen.TypeError: Das Argument vars () muss das Attribut __dict__ haben). dir () war nicht das, wonach ich gesucht habe: Es ist nur eine Auflistung von Feldnamen, gibt weder die Werte noch die Objektstruktur an.
Ich denke, json.dumps () würde für die meisten Objekte ohne den Standard = json_util.default funktionieren, aber ich hatte ein Datum / Uhrzeit-Feld im Objekt, so dass der Standard-JSON-Serializer fehlschlug. Siehe Wie man "datetime.datetime nicht JSON serialisierbar" in Python überwindet?
Warum nicht etwas Einfaches:
for key,value in obj.__dict__.iteritems():
print key,value
for key,value in obj.__dict__.iteritems(): print key,value
?
pprint enthält einen „hübschen Drucker“ zur Erstellung ästhetisch ansprechender Darstellungen Ihrer Datenstrukturen. Der Formatierer erzeugt Darstellungen von Datenstrukturen, die vom Interpreter korrekt analysiert werden können und für einen Menschen auch leicht zu lesen sind. Die Ausgabe wird nach Möglichkeit in einer einzelnen Zeile gehalten und bei Aufteilung auf mehrere Zeilen eingerückt.
Probieren Sie einfach Beeprint .
Es hilft Ihnen nicht nur beim Drucken von Objektvariablen, sondern auch bei der schönen Ausgabe wie folgt:
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)
Für alle, die damit zu kämpfen haben
vars()
nicht alle Attribute zurückgeben. dir()
Die Werte der Attribute werden nicht zurückgegeben.Der folgende Code druckt alle Attribute obj
mit ihren Werten:
for attr in dir(obj):
try:
print("obj.{} = {}".format(attr, getattr(obj, attr)))
except AttributeError:
print("obj.{} = ?".format(attr))
Sie können die Flask Debug-Symbolleiste ausprobieren.
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)
Ich arbeite gerne mit in Python-Objekten integrierten Schlüsseln oder Werten .
Für Attribute, unabhängig davon, ob es sich um Methoden oder Variablen handelt:
o.keys()
Für Werte dieser Attribute:
o.values()
Dies funktioniert unabhängig davon, wie Ihre Variablen innerhalb einer Klasse innerhalb oder außerhalb von __init__ definiert sind.
your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
__dict__
Mitglied zu haben (re.MatchObject
z. B. ein), aber die integrierte Funktiondir()
funktioniert für alle Objekte.