self.__class__
является ссылкой на тип текущего экземпляра.
Для экземпляров abstract1
, что был бы abstract1
класс сам, который является то, что вы не хотите с абстрактным классом. Абстрактные классы предназначены только для подклассов, чтобы не создавать экземпляры непосредственно:
>>> abstract1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated
Для экземпляра подкласса из abstract1
, self.__class__
будет ссылка на конкретный подкласс:
>>> class Foo(abstract1): pass
...
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True
Выбрасывание исключения здесь похоже на использование заявления assert
в другом месте вашего кода, оно защищает вас от глупых ошибок.
Обратите внимание, что вещий способ проверки типа экземпляра, чтобы использовать type()
function вместо этого, вместе с идентичности теста с is
оператора:
class abstract1(object):
def __init__(self):
if type(self) is abstract1:
raise NotImplementedError("Interfaces can't be instantiated")
Существует мало смысла используя тест равенства здесь как для пользовательских классов, __eq__
в принципе реализован как тест идентичности.
Python также включает стандартную библиотеку для определения абстрактных базовых классов, называемую abc
. Он позволяет отмечать методы и свойства как абстрактные и отказывается создавать экземпляры любого подкласса, который еще не переопределил эти имена.
Я думаю, это требует большего контекста. Где вы «нашли» этот код? Это в основном сломан. – Iguananaut
@Iguananaut: Почему это сломано? Он работает * отлично * при использовании по назначению; как абстрактный базовый класс. –
Я уверен, что раньше это было что-то другое? Я не знаю - согласен, что там сейчас не сломано. – Iguananaut