抽象基类_1

java只能继承一个类,但能继承多个接口,接口不能实例化。
python的抽象基类也不能实例化

class Company(object):
    def __len__(self):
        return 10
company = Company()
 # 当使用len()内置函数时,会首先调用__len__方法
print(len(company))
# 检查某个类是否有某种方法
# hasattr()内置函数:用于判断对象是否有某个属性
hasattr(company,"__len__") # 返回True

抽象基类用法1:

判定某个对象的类型——需要用到抽象基类

from collections.abc import Sized
print(isinstance(company,Sized))

抽象基类用法2:

强制某个子类必须实现某些方法——需要用到抽象基类

例如实现web框架,继承cache(redis,cache,memorycache)
需要设计一个抽象基类,指定子类必须实现某些方法——做框架时要考虑的

class CacheBase():
    def get(self, key):
        raise NotImplementedError
    def set(self, key, value):
        raise NotImplementedError
class RedisCache(CacheBase):
    pass
redis_cache = RedisCache()
# 在RedisCache中没有改写set\get方法,就去调用,会在基类中抛出异常
redis_cache.set()

抽象基类(abc模块)

在python中已经实现了通用的抽象基类collection的abc模块,即collection.abc,可了解python数据结构的接口
模拟实现一个抽象基类:未重写基类的抽象方法时,初始化就报错

import abc  # 全局下的abc
class CacheBase1(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def get(self, key):
        pass
    @abc.abstractmethod
    def set(self, key, value):
        pass
class RedisCache(CacheBase1):
    pass
# 这里会报错
redis_cache = RedisCache()
但要注意:抽象基类是很少使用的,抽象基类更像是说明文档!为了说明python中的某些属性,不推荐使用抽象基类!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的抽象基类(Abstract Base Class,简称ABC)是一种特殊的类,它定义了一组抽象方法,这些方法必须在子类中实现。ABC的一个主要用途是为了检查子类是否符合某个接口的规范。 在ABC中,可以使用`__subclasshook__`方法来判断一个类是否是该ABC的虚拟子类。具体来说,如果一个类没有直接继承该ABC,但是它的基类中有`__subclasshook__`方法,而且该方法返回True,则该类就被视为该ABC的虚拟子类。 下面是一个例子,我们定义了一个ABC `MyABC`,其中定义了一个抽象方法`my_method`。然后定义了一个普通类`MyClass`,它继承自`object`,并且实现了`my_method`方法。最后,我们在`MyClass`中定义了`__subclasshook__`方法,它判断一个类是否实现了`my_method`方法。 ```python from abc import ABC, abstractmethod class MyABC(ABC): @abstractmethod def my_method(self): pass class MyClass(object): def my_method(self): print("MyClass.my_method() is called") @classmethod def __subclasshook__(cls, C): if cls is MyABC: if hasattr(C, 'my_method'): return True return NotImplemented print(issubclass(MyClass, MyABC)) # True ``` 在上面的代码中,我们使用`issubclass`函数来检查`MyClass`是否是`MyABC`的子类。由于`MyClass`实现了`my_method`方法,而且定义了`__subclasshook__`方法,因此`issubclass(MyClass, MyABC)`返回True。 接下来我们实现一个自己的虚拟子类。我们定义一个普通类`MyClass2`,它没有直接继承自`MyABC`,但是它的基类中定义了`__subclasshook__`方法,该方法判断一个类是否实现了`my_method`方法。然后我们通过`register`方法将`MyClass2`注册为`MyABC`的虚拟子类。 ```python class MyClass2(object): def my_method(self): print("MyClass2.my_method() is called") @classmethod def __subclasshook__(cls, C): if cls is MyABC: if hasattr(C, 'my_method'): return True return NotImplemented MyABC.register(MyClass2) print(issubclass(MyClass2, MyABC)) # True ``` 在上面的代码中,我们使用`register`方法将`MyClass2`注册为`MyABC`的虚拟子类。然后我们再次使用`issubclass`函数来检查`MyClass2`是否是`MyABC`的子类。由于`MyClass2`实现了`my_method`方法,并且已经被注册为`MyABC`的虚拟子类,因此`issubclass(MyClass2, MyABC)`返回True。 总之,`__subclasshook__`方法是ABC中的一个重要方法,它可以让我们方便地判断一个类是否符合某个接口的规范。同时,我们也可以通过`register`方法将一个普通类注册为ABC的虚拟子类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值