Reflektion oder Introspektion ist eine Technik, wo das Programm etwas über sich selbst weiß. Es kann während des Ausführens Informationen über die Struktur von Datenstrukturen erfahren, und eventuell diese Strukturen auch dynamisch modifizieren.
type("abc")
str
# strings immer mit str, weil es kann auch "unicode" sein
# bei Python 2 aber mit "basestring" testen um sowohl "str" als auch "unicode" abzufangen
isinstance(u"abc", str)
True
l = [1,2,3]
t = (1,2,3)
isinstance(l, (list, tuple))
True
isinstance(t, (list, tuple))
True
x = "abc"
hasattr(x, "date")
False
hasattr(x, "__len__")
True
Statt der "." Notation, geht auch:
l = [1]
l.append(2)
getattr(l, "append")(3)
l
[1, 2, 3]
x = "abc"
# nur solche, die nicht mit "_" beginnen
print([a for a in dir(x) if not a.startswith("_")])
['capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
Eine Funktion, Konstruktur, etc.
from datetime import datetime
callable(datetime)
True
callable(42)
False
def f(x):
return 2*x
callable(f)
True
import inspect
def f2(k, l = "hello"):
return l * k
f2
Funktion¶print(inspect.getsource(f2))
def f2(k, l = "hello"): return l * k
f2
¶inspect.getargspec(f2)
ArgSpec(args=['k', 'l'], varargs=None, keywords=None, defaults=('hello',))
Während der Ausführung, kann man auch auf den Stack des Interpreters zugreifen.
x = 42
frame = inspect.currentframe()
print(inspect.getframeinfo(frame))
print("Lokale Variable x: %s" % frame.f_locals['x'])
Traceback(filename='<ipython-input-17-6cd23f46c278>', lineno=2, function='<module>', code_context=['frame = inspect.currentframe()\n'], index=0) Lokale Variable x: 42