Ich schrieb eine Metaklasse, die automatisch ihre Klassen in einem dict zur Laufzeit registriert. Damit es ordnungsgemäß funktioniert, muss es in der Lage sein, abstrakte Klassen zu ignorieren.Wie erkennt man, ob eine Klasse in Python 3 abstrakt ist?
Der Code funktioniert wirklich gut in Python 2, aber ich habe in eine Wand laufen versuchen, es zu machen kompatibel mit Python 3.
Hier ist, was der Code sieht aus wie zur Zeit:
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
Verwendung in Python 2 sieht wie folgt aus:
# 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
Was ich ca Aber wie funktioniert das in Python 3?
Wie kann eine Metaklasse bestimmen, ob eine abstrakte Klasse in Python 3 initialisiert wird?
Trotz der Verwendung von 'ABCMeta' sind Ihre angeblich" abstrakten "Klassen im Python 2-Code nicht wirklich abstrakt (das heißt, Sie können Instanzen von ihnen erstellen, wenn Sie möchten, und Python wird keine Ausnahme auslösen). Für etwas, das wirklich abstrakt ist, müssen Sie den '@ abstractmethod'-Dekorator für einige Methoden verwenden, die Sie darin deklarieren. Untergeordnete Klassen sind auch abstrakt, es sei denn, sie überschreiben diese Methoden (ohne den Dekorator selbst zu verwenden). Ich bin mir nicht sicher, ob eine vernünftige Antwort auf Ihre Frage gegeben werden kann, ohne dieses grundlegende Problem zuerst zu beheben. – Blckknght
Ich schätze die Eingabe. Ihr Kommentar veranlasste mich zu weiteren Untersuchungen, und ich sehe jetzt, dass mein ursprüngliches Verständnis von "abstrakt" nicht korrekt war. Ich muss darüber nachdenken; Wir verwenden dieses Muster häufig in unserer Codebasis, aber wenn wir letztendlich ein Werkzeug falsch verwenden, wird das auf lange Sicht zu großen Problemen führen. – user5568265