Are Python pure virtual functions possible and/or worth it?
我可能来自不同的思维方式,主要是C++程序员。这个问题与Python中的OOP以及更具体的纯虚拟方法有关。所以,根据这个问题改编的代码,我将看到这个基本示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Animal(): def speak(self): print("...") class Cat(Animal): def speak(self): print("meow") class Dog(Animal): def speak(self): print("woof") my_pets = [Dog(), Cat(), Dog()] for _pet in my_pets: _pet.speak() |
所以您可以看到它为不同的派生类调用speak函数。现在我的问题是鸭子打字很好,我想我已经掌握了。然而,在Python中追求更严格的OOP是错误的吗?所以我研究了抽象的基类和具体的抽象方法。对我来说,这一切似乎都是允许我用super调用基类方法。是否有任何方法/理由(在python中)使
我对这种追求的论点是,当你编写模块和框架时,你打算让人们子类化,这将为他们自我记录他们需要实现这个功能的事实。一个可能非常糟糕的想法是这样的,让基类"pure"函数抛出一个异常。问题是在运行时发现此错误!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class VirtualException(BaseException): def __init__(self, _type, _func): BaseException(self) class Animal(): def speak(self): raise VirtualException() class Cat(Animal): def speak(self): print("meow") class Dog(Animal): def speak(self): print("woof") class Wildebeest(Animal): def function2(self): print("What!") my_pets = [Dog(), Cat(), Dog(), Wildebeest()] for _pet in my_pets: _pet.speak() |
号
抽象基类已经满足了您的需要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | >>> class Foo(metaclass=abc.ABCMeta): ... @abc.abstractmethod ... def foo(self): ... pass ... >>> class Bar(Foo): ... pass ... >>> class Baz(Bar): ... def foo(self): ... return super(Baz, self).foo() ... >>> Foo() Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class Foo with abstract methods foo >>> Bar() Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class Bar with abstract methods foo >>> Baz() <__main__.Baz object at 0x00000210D702E2B0> |
号Python2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | >>> class Foo(object): ... __metaclass__ = abc.ABCMeta ... @abc.abstractmethod ... def foo(self): pass ... >>> class Bar(Foo): pass ... >>> class Baz(Bar): ... def foo(self): return super(Baz, self).foo() ... >>> Foo() Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class Foo with abstract methods foo >>> Bar() Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class Bar with abstract methods foo >>> Baz() <__main__.Baz object at 0x0000000001EC10B8> |
Problem is that this error is found at runtime!
号
嗯,是Python……大多数错误将在运行时出现。
据我所知,最常见的模式是在python中,基本上就是您所描述的:只要让基类的
1 2 3 | class Animal(): def speak(self): raise NotImplementedError('You need to define a speak method!') |