扩展抽象基类和派生自“对象”的类可以按您的预期工作:如果您还没有实现所有抽象方法和属性,则会出现错误。
奇怪的是,用扩展“异常”的类替换对象派生类允许您创建不实现所有必需抽象方法和属性的类的实例。
例如:
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."
...产量...
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
我知道“异常”因此“myCustomException”没有属性“foo”,那么为什么我要实例化“myCustomException”呢?
编辑:为了记录,这是我最终采用的骇人听闻的解决方法。不是真正等效的,但适用于我的目的。
# "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."