web-dev-qa-db-ja.com

子クラスに親のメソッドをオーバーライドさせる

次のように、実装されていないメソッドを持つ基本クラスがあるとします。

class Polygon():
    def __init__(self):
        pass

    def perimeter(self):
        pass

    def area(self):
        pass

ここで、同僚の1人がPolygonクラスを使用して、次のようにサブクラスを作成するとします。

import math

class Circle(Polygon):
    def __init__(self, radius):
        self.radius = radius

    def perimeter(self):
        return 2 * math.pi * self.radius

(H/Sh)eはarea()メソッドの実装を忘れています。

サブクラスに親のarea()メソッドを実装させるにはどうすればよいですか?

32
Aditya Barve

これはあなたの親クラスかもしれません:

_class Polygon():
    def __init__(self):
        raise NotImplementedError

    def perimeter(self):
        raise NotImplementedError

    def area(self):
        raise NotImplementedError
_

ただし、子クラスのインスタンスの1つがこれらのメソッドの1つを呼び出そうとすると、実行時にのみ問題が発見されます。


別のバージョンでは _abc.abstractmethod_ を使用します。

_from abc import ABCMeta, abstractmethod
# simpler alternative: from abc import ABC, abstractmethod
import math

class Polygon(metaclass=ABCMeta):
# simpler alternative: class Polygon(ABC)

    @abstractmethod
    def __init__(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

    @abstractmethod
    def area(self):
        pass

class Circle(Polygon):
    def __init__(self, radius):
        self.radius = radius

    def perimeter(self):
        return 2 * math.pi * self.radius

#    def area(self):
#        return math.pi * self.radius**2


c = Circle(9.0)
# TypeError: Can't instantiate abstract class Circle
#            with abstract methods area
_

すべてのメソッドを実装しないと、Circleをインスタンス化できません。

これは_python 3_構文です。 _python 2_で必要なこと

_class Polygon(object):
    __metaclass__ = ABCMeta
_

また、バイナリ特殊関数__eq__(), __lt__(), __add__(), ...の場合、NotImplementedErrorを上げるのではなく、 _return NotImplemented_ を使用することをお勧めします。

63

それがまさにNotImplementedErrorが使用されるものです:)

基本クラスで

def area(self):
    raise NotImplementedError("Hey, Don't forget to implement the area!")

基本クラスメソッドで NotImplementedError 例外を発生させることができます。

class Polygon:
    def area(self):
        raise NotImplementedError

また、 @abc.abstractmethod 、ただし、メタクラスを abc.ABCMeta 、これはクラスを抽象化します。 abc module の詳細

4
vishes_shell