Возможность создания экземпляра класса Python, несмотря на то, что это Abstract (с использованием abc)
Это относится к ответу на этот вопрос "Использовать модуль abc для создания абстрактных классов". (автор @alexvassel и принят в качестве ответа).
Я попробовал предложения, но как ни странно, несмотря на то, что следовал советам использовать abc
Кстати, это не работает для меня. Поэтому я выкладываю это как вопрос здесь:
Вот мой код Python:
from abc import ABCMeta, abstractmethod
class Abstract(object):
__metaclass__ = ABCMeta
@abstractmethod
def foo(self):
print("tst")
a = Abstract()
a.foo()
Когда я выполняю этот модуль, вот вывод на моей консоли:
pydev debugger: starting (pid: 20388)
tst
в отличие от этого принятого ответа
>>> TypeError: Can not instantiate abstract class Abstract with abstract methods foo
Так что я делаю правильно или неправильно? Почему работает и не подведет? Цените любое понимание эксперта в этом.
2 ответа
В Python 3 используйте metaclass
аргумент при создании абстрактного базового класса:
from abc import ABCMeta, abstractmethod
class Abstract(metaclass=ABCMeta):
@abstractmethod
def foo(self):
print("tst")
a = Abstract()
a.foo()
В Python 2 вы должны назначить метакласс следующим образом:
import abc
class ABC(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def foo(self):
return True
a = ABC()
Который поднимает TypeError
Traceback (most recent call last):
File "<pyshell#59>", line 1, in <module>
a = ABC()
TypeError: Can't instantiate abstract class ABC with abstract methods foo
Но в Python 3, присваивая __metaclass__
поскольку атрибут не работает (как вы и предполагали, но интерпретатор не считает его ошибкой, просто обычный атрибут, как и любой другой, поэтому вышеприведенный код не вызывает ошибку). Метаклассы теперь определены как именованный аргумент класса:
import abc
class ABC(metaclass=abc.ABCMeta):
@abc.abstractmethod
def foo(self):
return True
a = ABC()
поднимает TypeError
:
Traceback (most recent call last):
File "main.py", line 11, in
a = ABC()
TypeError: Can't instantiate abstract class ABC with abstract methods foo