Die Erweiterung einer abstrakten Basisklasse und einer von "object" abgeleiteten Klasse funktioniert wie erwartet: wenn Sie nicht implementiert haben Bei allen abstrakten Methoden und Eigenschaften erhalten Sie einen Fehler.Python abc-Modul: Erweiterung einer abstrakten Basisklasse und einer ausnahmebedingten Klasse führt zu einem überraschenden Verhalten
Seltsamerweise können Sie durch das Ersetzen der vom Objekt abgeleiteten Klasse durch eine Klasse, die "Exception" erweitert, Instanzen von Klassen erstellen, die nicht alle erforderlichen abstrakten Methoden und Eigenschaften implementieren.
Zum Beispiel:
import abc
# The superclasses
class myABC(object):
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def foo(self):
pass
class myCustomException(Exception):
pass
class myObjectDerivedClass(object):
pass
# Mix them in different ways
class myConcreteClass_1(myCustomException, myABC):
pass
class myConcreteClass_2(myObjectDerivedClass, myABC):
pass
# Get surprising results
if __name__=='__main__':
a = myConcreteClass_1()
print "First instantiation done. We shouldn't get this far, but we do."
b = myConcreteClass_2()
print "Second instantiation done. We never reach here, which is good."
... Ausbeuten ...
First instantiation done. We shouldn't get this far, but we do.
Traceback (most recent call last):
File "C:/Users/grahamf/PycharmProjects/mss/Modules/mssdevice/sutter/sutter/test.py", line 28, in <module>
b = myConcreteClass_2()
TypeError: Can't instantiate abstract class myConcreteClass_2 with abstract methods foo
Ich weiß, dass "Ausnahme" und deshalb "myCustomException" haben kein Attribut "foo", also warum bin ich weg mit der Instanziierung "myCustomException"?
EDIT: Für die Aufzeichnung ist dies die hackish Workaround, die ich mit ging. Nicht wirklich gleichwertig, aber funktioniert für meine Zwecke.
# "abstract" base class
class MyBaseClass(Exception):
def __init__(self):
if not hasattr(self, 'foo'):
raise NotImplementedError("Please implement abstract property foo")
class MyConcreteClass(MyBaseClass):
pass
if __name__=='__main__':
a = MyConcreteClass()
print "We never reach here, which is good."
Danke! Das ist interessant. Ich kann mir keine Problemumgehung für das, was ich versuche, vorstellen, die nicht hack-ish ist. –
Verwandte Themen für Menschen mit diesem Problem: [hier] (http://stackoverflow.com/questions/2862153/python-2-6-3-abstract-base-class-misunderstanding/2862419#2862419) und [hier] (http://stackoverflow.com/questions/20107530/can-one-declare-an-abstract-exception-in-python) –