python 强制子类重新实现父类方法
python 强制子类重新实现父类方法
L很失败L 发表于1年前
python 强制子类重新实现父类方法
  • 发表于 1年前
  • 阅读 321
  • 收藏 2
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

摘要: 有时候父类只是定义接口,并没有具体实现,这时候就要求子类必须自己实现一次,

有这么一个情景:

父类定义方法后,并没有具体实现.

这时候子类就必须自己实现一遍,但是按照继承的规则,子类可以不实现,可以调用父类的方.

.这时问题就出现了,父类没有定义,子类没有定义,这个方法还被调用了,那调用就出了问题.

为了强制子类必须实现这种方法,防止后边出错,我找到了两种实现机制.

但是由于python是解释运行,所以这个""强制",必须在运行时才能发现.

一.  NotImplementedError

raise NotImplementedError

字面看就能看出啥意思.在父类定义方法,要求子类必须自行实现时,可以在定义函数中这样写.

class first:
    def in_first(self):
        raise NotImplementedError

class second(first):
    pass

instance_from_second = second()
instance_from_second.in_first()# <== NotImplementedError

如果子类没有实现就会触发 NotImplementedError 的异常,这时就知道这个方法在子类中没有实现.

二. abstractmethod

这是python标准库abc中的一个强制机制,在abc模块中.这个强制触发异常不是在调用那个方法时,而是子类实例化时.不过这种有两个要求,1. __metaclass__必须为 ABCMeta;2. 方法必须加 abstractmethod  修饰.

from abc import ABCMeta,abstractmethod
class first:
    __metaclass__ = ABCMeta
    @abstractmethod
    def in_first(self):
        print "haha"

class second(first):
    pass

instance_from_second = second() # <== TypeError: Can't instantiate abstract class second with abstract methods in_first
instance_from_second.in_first() # will not run

这两者更推荐使用后面的 abstractmethod ,原因有两个.

1. 使用 abstractmethod ,发现这个问题的更快.它是在实例化时检查的,相比第一种方法是在调用时才发现,要更快一些,不用浪费时间.

2.使用 abstractmethod修饰 ,也是可以调用父类中的这个方法的.(官方文档说与 java 的 abstractmethod 不同,然而我不会java啊).相比第一种方法调用触发异常,更全面一些,比如子类都要用的写在父类还是有必要的.

这里就要使用神奇的super()方法.

from abc import ABCMeta,abstractmethod
class first:
    __metaclass__ = ABCMeta
    @abstractmethod
    def in_first(self):
        print "haha"

class second(first):
    def in_first(self):
        super(second, self).in_first()
        print "haha2"


instance_from_second = second()
instance_from_second.in_first()

#output:
#haha
#haha2

关于abc模块的更加详细介绍可以参见 : abc – Abstract Base Classes

关于python abstract method的讨论可参见 : Abstract methods in Python

标签: python abstract method
共有 人打赏支持
粉丝 2
博文 14
码字总数 7388
×
L很失败L
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: