Was ich hier also suche, ist so etwas wie PHPs drucken_r Funktion.
So kann ich meine Skripte debuggen, indem ich den Zustand des betreffenden Objekts sehe.
Was ich hier also suche, ist so etwas wie PHPs drucken_r Funktion.
So kann ich meine Skripte debuggen, indem ich den Zustand des betreffenden Objekts sehe.
Sie vermischen hier wirklich zwei verschiedene Dinge miteinander.
Utilisez dir()
, vars()
oder die inspect
Modul, um das zu bekommen, was Sie interessiert (ich verwende __builtins__
als Beispiel; Sie können stattdessen jedes beliebige Objekt verwenden).
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__
Drucken Sie das Wörterbuch aus, wie es Ihnen gefällt:
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...
ou
>>> 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',
...
Pretty-Printing 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__'}
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 die Behandlung von Ausnahmen, die Ausgabe von nationalen Zeichen/Sonderzeichen, die Suche nach verschachtelten Objekten usw. je nach den Wünschen ihrer Autoren hinzufügen. Aber im Grunde laufen sie alle auf das Folgende hinaus.
Gibt es eine eingebaute Funktion, die alle aktuellen Eigenschaften und Werte eines Objekts ausgibt?
Nein. Die am meisten hochgestimmte Antwort schließt einige Arten von Attributen aus, und die akzeptierte Antwort zeigt, wie man todo Attribute, einschließlich Methoden und Teile der nicht-öffentlichen API. Aber es gibt keine gute vollständige eingebautes Funktion dafür.
Die kurze Konsequenz ist also, dass Sie Ihre eigene schreiben können, aber sie wird Eigenschaften und andere berechnete Daten-Deskriptoren berechnen, die Teil der öffentlichen API sind, und das wollen Sie vielleicht 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))
Beobachten Sie die Anwendung der aktuell am häufigsten gewählten Antwort auf eine Klasse mit vielen verschiedenen Arten von Datenmitgliedern:
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'}
Denn vars
nur __dict__
eines Objekts, und es ist keine Kopie. Wenn Sie also das von vars zurückgegebene dict ändern, ändern Sie auch das __dict__
des Objekts selbst.
vars(obj)['quux'] = 'WHAT?!'
vars(obj)
zurück:
{'baz': 'baz', 'quux': 'WHAT?!'}
-- was schlecht ist, weil quux eine Eigenschaft ist, die wir nicht setzen sollten und die nicht im Namensraum sein sollte...
Die Anwendung der Ratschläge in der derzeit 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, dir
kehrt nur zurück todo (eigentlich nur die meisten) der mit einem Objekt verbundenen Namen.
inspect.getmembers
die in den Kommentaren erwähnt wurde, ist ähnlich fehlerhaft - sie liefert alle Namen und Werte.
Im Unterricht lasse ich meine Studenten 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 kopieren. des semantischen Namensraums eines Objekts, aber wir müssen ausschließen __slots__
die nicht zugewiesen sind, und wenn wir die Forderung nach "aktuellen Eigenschaften" ernst nehmen, müssen wir berechnete Eigenschaften ausschließen (da sie teuer werden könnten und als nicht "aktuell" interpretiert werden könnten):
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 nicht die Eigenschaft, quux:
>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}
Aber vielleicht wissen wir ja, dass unsere Immobilien nicht teuer sind. Vielleicht wollen wir die Logik so ändern, dass auch sie berücksichtigt werden. Und vielleicht wollen wir ausschließen andere benutzerdefinierte stattdessen Daten-Deskriptoren.
Dann müssen wir diese Funktion weiter anpassen. Daher ist es logisch, dass wir keine eingebaute Funktion haben können, die auf magische Weise genau weiß, was wir wollen und es bereitstellt. Diese Funktion müssen wir selbst erstellen.
Es gibt keine eingebaute Funktion, die dies tut, und Sie sollten tun, was für Ihre Situation semantisch am besten geeignet ist.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.