2.33. Introspekce

Hrstka vestavěných funkcí umožňuje běžícímu programu zkoumat sám sebe – hodnoty, se kterými pracuje, jmenné prostory, v nichž tyto hodnoty žijí, a vztahy mezi třídami. Sáhněte po nich, když potřebujete rozhodovat na základě toho, čím objekt skutečně je, spíše než toho, co o něm tvrdí jeho volající.

2.33.1. Identita a hashování

  • id() – jedinečné celé číslo, které identifikuje objekt po celou dobu, kdy je naživu. Dvě jména navázaná na stejný objekt vrátí stejné id; dva stejné, ale odlišné objekty nikoli.

>>> a = [1, 2, 3]
>>> b = a
>>> c = [1, 2, 3]
>>> id(a) == id(b)        # same list
True
>>> id(a) == id(c)        # equal but distinct
False

Id není přenosné napříč spuštěními a nemá význam mimo „stejný objekt, nebo jiný objekt.“

  • hash() – hodnota hashe objektu, totéž číslo, které dict a set používají k jeho vyhledání. Dva stejné objekty se hashují na stejnou hodnotu; vůbec fungují pouze hashovatelné typy (většinou neměnné hodnoty).

>>> hash("abc")           # some integer, build-dependent
-1600925533
>>> hash([1, 2])
TypeError: unhashable type: 'list'

2.33.2. Dotazování na typy a volatelnost

  • type() – přesná třída hodnoty. type(x) is int se ptá „je x přesně int“ (žádné podtřídy); isinstance() je obvykle to, co chcete místo toho.

  • isinstance() – „je x instancí této třídy, nebo její podtřídy?“ Standardní nástroj pro rozhodování na základě typu uvnitř funkcí.

  • issubclass() – protějšek na úrovni tříd. Přijímá dvě třídy namísto instance.

  • callable()True, pokud lze argument zavolat pomocí (). Užitečné, když přijmete argument, který může být funkce nebo prostá hodnota.

>>> isinstance(3, int)
True
>>> isinstance(True, int)        # bool is a subclass of int
True
>>> issubclass(bool, int)
True
>>> callable(len)
True
>>> callable(10)
False

Vzor, který používá callable:

def call_or_return(x):
    return x() if callable(x) else x

2.33.3. Pohled do rozsahů

  • globals() – globální jmenný prostor modulu jako dict. Čtení z něj funguje; zápis do něj je reálný, ale dělat to mimo zkoumání v REPL činí program obtížně sledovatelným.

  • locals() – lokální jmenný prostor v místě volání. Uvnitř funkce odráží lokální proměnné; úprava vráceného slovníku nemá zaručeno, že se zapíše zpět do skutečných lokálních proměnných (chování závislé na implementaci).

name = "OpenMV"

def f():
    x = 10
    print(globals()["name"])    # OpenMV
    print(locals())             # {'x': 10}

Tyto dvě jsou užitečné pro ladění a pro nástroje, které potřebují zjistit, co je definováno. V běžném kódu po nich sahejte střídmě – funkce, která mění globals(), patří k tomu nejhůře pochopitelnému v Pythonu.

2.33.4. Viz také

dir() a help(), popsané v debugging, jsou každodenní introspekční nástroje pro zkoumání povrchu neznámého objektu.