2.33. Інтроспекція¶
Кілька вбудованих функцій дозволяють запущеній програмі перевіряти саму себе — значення, з якими вона працює, простори імен, де живуть ці значення, та зв’язки між класами. Звертайтеся до них, коли вам потрібно приймати рішення на основі того, чим об’єкт насправді є, а не того, чим його виклик стверджує, що він є.
2.33.1. Ідентичність та хешування¶
id()– унікальне ціле число, що ідентифікує об’єкт, поки він живий. Два імені, що прив’язані до одного об’єкта, повертають однаковий id; два рівних, але різних об’єкти — ні.
>>> 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 не є портабельним між запусками і не має значення поза «однаковий об’єкт чи різний».
hash()– хеш-значення об’єкта, той самий номер, якийdictтаsetвикористовують для його пошуку. Два рівних об’єкти мають однаковий хеш; працюють лише хешовані типи (здебільшого незмінні значення).
>>> hash("abc") # some integer, build-dependent
-1600925533
>>> hash([1, 2])
TypeError: unhashable type: 'list'
2.33.2. Запит типів та можливості виклику¶
type()– точний клас значення.type(x) is intзапитує «чи є x точно int» (без підкласів); замість цього зазвичай використовуютьisinstance().isinstance()– «чи є x екземпляром цього класу або його підкласу?» Стандартний інструмент для диспетчеризації на основі типу всередині функцій.issubclass()– аналог на рівні класу. Приймає два класи замість екземпляра.callable()–True, якщо аргумент можна викликати з(). Корисно, коли отримуєте аргумент, який може бути функцією або звичайним значенням.
>>> isinstance(3, int)
True
>>> isinstance(True, int) # bool is a subclass of int
True
>>> issubclass(bool, int)
True
>>> callable(len)
True
>>> callable(10)
False
Шаблон з використанням callable:
def call_or_return(x):
return x() if callable(x) else x
2.33.3. Перегляд областей видимості¶
globals()– глобальний простір імен модуля якdict. Читання з нього працює; запис до нього реальний, але робити це поза дослідженням у REPL ускладнює розуміння програми.locals()– локальний простір імен у місці виклику. Всередині функції відображає локальні змінні; зміна поверненого словника не гарантує запис назад у фактичні локальні змінні (поведінка, визначена реалізацією).
name = "OpenMV"
def f():
x = 10
print(globals()["name"]) # OpenMV
print(locals()) # {'x': 10}
Ці дві функції корисні для налагодження та для інструментів, яким потрібно дізнатися, що визначено. Використовуйте їх ощадливо у звичайному коді — функція, яка змінює globals(), є однією з найважчих речей для розуміння в Python.
2.33.4. Дивіться також¶
dir() та help(), розглянуті у debugging, є повсякденними інструментами інтроспекції для дослідження поверхні невідомого об’єкта.