Простая примесь, которую можно добавить к любому классу, чтобы разрешить подсчет экземпляров
В этом руководстве я объясню очевидный способ написания счетчика экземпляров на Python, а затем покажу, как его можно улучшить.
Зачем считать экземпляры?
Во-первых, зачем нам подсчитывать экземпляры объекта? Вот несколько примеров использования:
- Мы хотим дать объектам уникальные идентификаторы во время выполнения.
- Мы хотим отслеживать или подсчитывать создание экземпляров в целях отладки.
- Количество экземпляров среды выполнения имеет некоторое значение для нашей программы (например, нам нужно отсортировать объекты по порядку создания).
Основной подход
Простой подход к подсчету экземпляров - просто добавить его прямо в свой класс:
class A:
numInstances = 0
def __init__(self):
A.numInstances += 1
self.count = A.numInstances
Это создает переменную класса с именем numInstances
, которая отслеживает общее количество созданных экземпляров, и переменную экземпляра с именем count
, которая содержит номер экземпляра для данного экземпляра.
So:
a = A() b = A() a.count # returns 1 b.count # returns 2 a.numInstances # returns 2 b.numInstances # returns 2
Делаем его многоразовым
Конечно, как хорошие программисты, мы хотим сделать эту функцию подсчета многоразовой. Затем несколько классов можно подсчитать независимо, унаследовав некоторый заранее созданный Countable
класс.
Наш первый инстинкт - сделать что-то вроде этого:
class B : A pass # implement specialist functionality in B
Проблема в том, что B
и A
теперь используют одну и ту же переменную numInstances
, предоставленную A
, что дает нам:
b = B() b.count # returns 3, not 1 as expected
Однако есть способ решить эту проблему с помощью метаклассов Python. Это позволяет нам создать отдельное количество экземпляров для каждого подкласса:
Класс Countable
теперь можно использовать как миксин:
class A(Countable): pass class B (Countable): pass a = A() b = B() a.count # prints 1 b.count # also prints 1. numInstances is no longer shared
Спасибо за прочтение. Если вы нашли это полезным, ознакомьтесь с другими моими статьями на Medium: