我发现将抽象方法分成两种方法似乎很有用,一种用于公共接口,另一种用于被子类覆盖。
通过这种方式,您可以为输入和输出添加前置条件/后置条件检查,使其能够抵御人为错误。
但我在这里关心的是它是否在 python 上可以接受,因为在我的小经验中我从未见过这样的代码。
正常多态性
import abc
class Shape:
"""Abstract base class for shapes"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def get_area(self, scale):
"""Calculates the area of the shape, scaled by a factor.
Do not blame for a silly example.
"""
pass
class Rectangle(Shape):
def __init__(self, left, top, width, height):
self.left = left
self.top = top
self.width = width
self.height = height
def get_area(self, scale):
return scale * self.width * self.height
print(Rectangle(10, 10, 40, 40).get_area(3))
# Gosh!... gets tons of 3's
print(Rectangle(10, 10, 40, 40).get_area((3,)))
实现方法分离
import abc
class Shape:
"""Abstract base class for shapes"""
__metaclass__ = abc.ABCMeta
def get_area(self, scale):
"""Calculates the area of the shape, scaled by a factor"""
# preconditions
assert isinstance(scale, (int,float))
assert scale > 0
ret = self._get_area_impl(scale)
# postconditions
assert isinstance(ret, (int,float))
assert ret > 0
return ret
@abc.abstractmethod
def _get_area_impl(self, scale):
"""To be overridden"""
pass
class Rectangle(Shape):
def __init__(self, left, top, width, height):
self.left = left
self.top = top
self.width = width
self.height = height
def _get_area_impl(self, scale):
return scale * self.width * self.height
print(Rectangle(10, 10, 40, 40).get_area(3))
print(Rectangle(10, 10, 40, 40).get_area((3,))) # Assertion fails