2.33. Introspektio¶
Kourallinen sisäänrakennettuja funktioita antaa käynnissä olevan ohjelman tarkastella itseään – arvoja, joiden kanssa se työskentelee, nimiavaruuksia, joissa nuo arvot elävät, ja luokkien välisiä suhteita. Tartu niihin, kun sinun täytyy tehdä päätöksiä sen perusteella, mitä olio todella on, eikä sen perusteella, mitä sen kutsuja väittää sen olevan.
2.33.1. Identiteetti ja tiivisteet¶
id()– yksilöllinen kokonaisluku, joka tunnistaa olion niin kauan kuin se on elossa. Kaksi nimeä, jotka sitovat saman olion, palauttavat saman id:n; kaksi yhtä suurta mutta erillistä oliota eivät.
>>> 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 ei ole siirrettävissä ajokertojen välillä eikä se ole merkityksellinen muutoin kuin tarkoittaen ”sama olio tai eri olio”.
hash()– olion tiivistearvo, sama luku jotadictjasetkäyttävät sen hakemiseen. Kaksi yhtä suurta oliota tiivistyvät samaan arvoon; vain tiivistettävät tyypit (enimmäkseen muuttumattomat arvot) toimivat lainkaan.
>>> hash("abc") # some integer, build-dependent
-1600925533
>>> hash([1, 2])
TypeError: unhashable type: 'list'
2.33.2. Tyyppien ja kutsuttavuuden kysely¶
type()– arvon tarkka luokka.type(x) is intkysyy ”onko x tarkalleen int” (ei aliluokkia);isinstance()on yleensä se, mitä haluat sen sijaan.isinstance()– ”onko x tämän luokan tai sen aliluokan ilmentymä?” Vakiotyökalu tyyppipohjaiseen jakeluun funktioiden sisällä.issubclass()– luokkatason vastine. Ottaa kaksi luokkaa ilmentymän sijaan.callable()–True, jos argumentti voidaan kutsua()-merkinnällä. Hyödyllinen, kun saat argumentin, joka voi olla funktio tai tavallinen arvo.
>>> isinstance(3, int)
True
>>> isinstance(True, int) # bool is a subclass of int
True
>>> issubclass(bool, int)
True
>>> callable(len)
True
>>> callable(10)
False
Malli, joka käyttää funktiota callable:
def call_or_return(x):
return x() if callable(x) else x
2.33.3. Näkyvyysalueiden tarkastelu¶
globals()– moduulin globaali nimiavaruusdict-oliona. Siitä lukeminen toimii; siihen kirjoittaminen on todellista, mutta sen tekeminen REPL-tutkimisen ulkopuolella tekee ohjelmasta vaikeaselkoisen.locals()– paikallinen nimiavaruus kutsupaikassa. Funktion sisällä se heijastaa paikallisia muuttujia; palautetun sanakirjan muokkaaminen ei takaa kirjoittamista takaisin todellisiin paikallisiin muuttujiin (toteutuskohtainen käyttäytyminen).
name = "OpenMV"
def f():
x = 10
print(globals()["name"]) # OpenMV
print(locals()) # {'x': 10}
Nämä kaksi ovat hyödyllisiä virheenkorjauksessa ja työkaluille, joiden täytyy selvittää mitä on määritelty. Tartu niihin säästeliäästi tavallisessa koodissa – funktio, joka muuttaa globals() -nimiavaruutta, on yksi vaikeimmin järkeiltäviä asioita Pythonissa.
2.33.4. Katso myös¶
dir() ja help(), jotka käsitellään sivulla debugging, ovat jokapäiväiset introspektiotyökalut tuntemattoman olion pinnan tutkimiseen.