2.33. Introspekció

Néhány beépített függvény lehetővé teszi, hogy egy futó program megvizsgálja önmagát – az értékeket, amelyekkel dolgozik, a névtereket, amelyekben ezek az értékek élnek, és az osztályok közötti kapcsolatokat. Nyúlj hozzájuk, amikor az alapján kell döntéseket hoznod, hogy egy objektum valójában mi, nem pedig az alapján, aminek a hívója állítja.

2.33.1. Azonosság és hashelés

  • Az id() – egy egyedi egész szám, amely azonosít egy objektumot, ameddig az életben van. Két név, amely ugyanazt az objektumot köti, ugyanazt az id-t adja vissza; két egyenlő, de különböző objektum nem.

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

Az id nem hordozható futtatások között, és nem jelent többet, mint hogy „ugyanaz az objektum vagy különböző objektum”.

  • A hash() – egy objektum hash értéke, ugyanaz a szám, amelyet a dict és a set használ a megkereséséhez. Két egyenlő objektum ugyanarra az értékre hashel; egyáltalán csak hashelhető típusok (többnyire megváltoztathatatlan értékek) működnek.

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

2.33.2. Típusok és hívhatóság lekérdezése

  • A type() – egy érték pontos osztálya. A type(x) is int azt kérdezi, hogy „x pontosan egy int-e” (alosztályok nélkül); helyette általában az isinstance() az, amire szükséged van.

  • Az isinstance() – „x ennek az osztálynak, vagy egy alosztályának a példánya-e?” A szabványos eszköz a típusalapú elágaztatáshoz függvényeken belül.

  • Az issubclass() – az osztály szintű megfelelője. Egy példány helyett két osztályt vesz át.

  • A callable()True, ha az argumentum meghívható a () operátorral. Hasznos, amikor olyan argumentumot kapsz, amely lehet függvény, vagy lehet egyszerű érték.

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

Egy minta, amely a callable függvényt használja:

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

2.33.3. Hatókörök vizsgálata

  • A globals() – a modul globális névtere dict formában. Az olvasás belőle működik; az írás bele valódi, de a REPL felfedezésén kívül ezt megtenni nehezen követhetővé tesz egy programot.

  • A locals() – a lokális névtér a hívás helyén. Egy függvényen belül a lokális változókat tükrözi; a visszaadott dict módosítása nem garantáltan ír vissza a tényleges lokális változókba (implementációfüggő viselkedés).

name = "OpenMV"

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

Ez a kettő hasznos a hibakereséshez és olyan eszközökhöz, amelyeknek fel kell deríteniük, mi van definiálva. Takarékosan nyúlj hozzájuk a szokásos kódban – egy függvény, amely módosítja a globals() névteret, az egyik legnehezebben átlátható dolog a Pythonban.

2.33.4. Lásd még

A dir() és a help(), amelyeket a debugging tárgyal, a mindennapos introspekciós eszközök egy ismeretlen objektum felületének felderítéséhez.