2.33. Introspeksi

Sekelompok built-in memungkinkan program yang sedang berjalan untuk memeriksa dirinya sendiri -- nilai-nilai yang sedang dikerjakan, namespace tempat nilai-nilai itu berada, dan hubungan antar kelas. Gunakan ketika Anda perlu membuat keputusan berdasarkan apa yang sebenarnya dimiliki objek, bukan apa yang diklaim pemanggilnya.

2.33.1. Identitas dan hashing

  • id() -- bilangan bulat unik yang mengidentifikasi objek selama objek itu masih hidup. Dua nama yang mengikat objek yang sama mengembalikan id yang sama; dua objek yang setara tetapi berbeda tidak.

>>> 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 tidak portabel antar eksekusi dan tidak bermakna lebih dari "objek yang sama atau objek berbeda."

  • hash() -- nilai hash dari sebuah objek, angka yang sama yang digunakan dict dan set untuk mencarinya. Dua objek yang setara di-hash ke nilai yang sama; hanya tipe yang dapat di-hash (nilai yang tidak dapat diubah, sebagian besar) yang dapat bekerja.

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

2.33.2. Menanyakan tipe dan kemampuan pemanggilan

  • type() -- kelas persis dari sebuah nilai. type(x) is int bertanya "apakah x persis sebuah int" (tanpa subkelas); isinstance() biasanya yang Anda inginkan.

  • isinstance() -- "apakah x merupakan instance dari kelas ini, atau subkelasnya?" Alat standar untuk dispatch berbasis tipe di dalam fungsi.

  • issubclass() -- padanannya di tingkat kelas. Menerima dua kelas bukan sebuah instance.

  • callable() -- True jika argumen dapat dipanggil dengan (). Berguna ketika Anda menerima argumen yang mungkin berupa fungsi atau mungkin berupa nilai biasa.

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

Pola yang menggunakan callable:

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

2.33.3. Melihat scope

  • globals() -- namespace global modul sebagai sebuah dict. Membacanya berfungsi; menulis ke dalamnya nyata, tetapi melakukannya di luar eksplorasi REPL membuat program sulit diikuti.

  • locals() -- namespace lokal di titik pemanggilan. Di dalam fungsi, ini mencerminkan variabel lokal; memodifikasi dict yang dikembalikan tidak dijamin menulis kembali ke lokal yang sebenarnya (perilaku yang bergantung pada implementasi).

name = "OpenMV"

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

Keduanya berguna untuk debugging dan untuk alat yang perlu menemukan apa yang terdefinisi. Gunakan secara hemat dalam kode biasa -- fungsi yang memutasi globals() adalah salah satu hal yang paling sulit dipikirkan dalam Python.

2.33.4. Lihat juga

dir() dan help(), yang dibahas di debugging, adalah alat introspeksi sehari-hari untuk menjelajahi permukaan objek yang tidak dikenal.