Я написал метакласс, который автоматически регистрирует свои классы в dict во время выполнения. Чтобы он работал правильно, он должен уметь игнорировать абстрактные классы.Как определить, является ли класс абстрактным в Python 3?
код работает очень хорошо в Python 2, но я запустить в стену, пытаясь сделать его совместимым с Python 3.
Вот что код выглядит в настоящее время:
def AutoRegister(registry, base_type=ABCMeta):
class _metaclass(base_type):
def __init__(self, what, bases=None, attrs=None):
super(_metaclass, self).__init__(what, bases, attrs)
# Do not register abstract classes.
# Note that we do not use `inspect.isabstract` here, as
# that only detects classes with unimplemented abstract
# methods - which is a valid approach, but not what we
# want here.
# :see: http://stackoverflow.com/a/14410942/
metaclass = attrs.get('__metaclass__')
if not (metaclass and issubclass(metaclass, ABCMeta)):
registry.register(self)
return _metaclass
Использование в Python 2 выглядит следующим образом:
# Abstract classes; these are not registered.
class BaseWidget(object): __metaclass__ = AutoRegister(widget_registry)
class BaseGizmo(BaseWidget): __metaclass__ = ABCMeta
# Concrete classes; these get registered.
class AlphaWidget(BaseWidget): pass
class BravoGizmo(BaseGizmo): pass
Что ча не выяснять, однако, как это сделать в Python 3.
Как метакласс определить, если он инициализирует абстрактный класс в Python 3?
Несмотря на использование 'ABCMeta', ваши якобы« абстрактные »классы в коде Python 2, который вы показываете, на самом деле не абстрактны (т. Е. Вы можете создавать экземпляры, если хотите, и Python не будет создавать исключение). Чтобы что-то действительно было абстрактным, вам нужно использовать декоратор '@ abstractmethod' для некоторых методов, которые вы заявляете в нем. Классы для детей также будут абстрактными, если они не переопределяют эти методы (без использования самих декораторов). Я не уверен, что здравый ответ можно ответить на ваш вопрос, не исправляя этот фундаментальный вопрос в первую очередь. – Blckknght
Я ценю вход. Ваш комментарий побудил меня продолжить некоторые исследования, и теперь я вижу, что мое первоначальное понимание «абстрактного» было неправильным. Мне нужно подумать об этом; мы часто используем этот шаблон в нашей кодовой базе, но если мы в конечном счете используем инструмент не по-другому, это вызовет серьезные проблемы в долгосрочной перспективе. – user5568265