python 抽象基类

具体化抽象基类的两种方式:

1、通过抽象基类 ABCMeta 的 register 方法注册。

2、通过继承的方式。

class Base(metaclass = ABCMeta):
	@classmethod
	def __subclasshook__(cls, subclass):
		if cls is Base:
			return True
		return NotImplemented

class Derive(Base):
	pass
print(issubclass(int, Base))  #True
print(issubclass(int, Derive))  #False

issubclass 放回会调用 __subclasscheck__,isinstance 会调用 __instancecheck__.

issubclass(int, Base) 调用 Base.__subclasscheck__(int) 方法。Base.__subclasscheck__ 方法来自 ABCMate 元类。

调用 ABCMate 的 __subclasscheck__ 方法,ABCMate 的 __subclasscheck__ 返回会调用 __subclasshook__ 方法。

    def __subclasscheck__(cls, subclass):
        """Override for issubclass(subclass, cls)."""
        # Check cache
        if subclass in cls._abc_cache:
            return True
        # Check negative cache; may have to invalidate
        if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
            # Invalidate the negative cache
            cls._abc_negative_cache = WeakSet()
            cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
        elif subclass in cls._abc_negative_cache:
            return False
        # Check the subclass hook
        ok = cls.__subclasshook__(subclass)   #check 方法调用 hook
        if ok is not NotImplemented:
            assert isinstance(ok, bool)
            if ok:
                cls._abc_cache.add(subclass)
            else:
                cls._abc_negative_cache.add(subclass)
            return ok

if cls is Base: 确保了只有 Base 类自己调用该方法时,走这一分支;如果是 Base 类的派生类调用,则走下一分支,返回 NotImplemented  走默认实现。

__subclasscheck__ 检查一个类是否是另外一个类的子类,所以只能用在元类上。

issubclass(MySubCls, MyCls)
#等价于 MyCls.__subclasscheck(MySubCls)

 

抽象基类的用处:
1、继承自抽象基类,必须实现抽象基类的所有 abstractmethod ,这样在对象创建阶段就会检查,而不用等到调用方法时。
2、将 ducktype 的检测(是否拥有某方法)统一到 issubclass 和 isinstance 上。
如果正确的实现了接口,便是子类,而不用通过继承的方式。

hasattr(x, '__iter__') 替换成 isinstance(x, collections.Iterable)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值