python抽象基类都有哪些_python 抽象基类

#抽象基类是一个分配身份的机制

# 声明虚拟子类 ABCMeta抽象基类的元类

import abc

class AbstractDict(metaclass=abc.ABCMeta):

def foo(self):

return None

ab = AbstractDict.register(dict)

print(ab)

# print(ab.foo())

print(isinstance({},AbstractDict))

print(issubclass(dict,AbstractDict))

# 声明虚拟子类的原因

# 抽象基类可以提供一个非常好的扩展机制,示例如下:

class MySequence(metaclass=abc.ABCMeta):

pass

MySequence.register(list)

MySequence.register(tuple)

print(isinstance([],MySequence))

print(isinstance((),MySequence))

print(isinstance(object(),MySequence))

class CustomListLikeClass(object):

pass

MySequence.register(CustomListLikeClass)

print('object*************************')

print(isinstance(CustomListLikeClass(),MySequence))

#python3.3以来register方法可以作为装饰器,因为register方法返回类,3.3版本之前返回None,因此不能作为装饰器

@MySequence.register

class CustomListLikeClass(object):

pass

class AbstractDuck(metaclass=abc.ABCMeta):

"""该抽象基类声明,任何带有quack方法的类都被认为是他的子类"""

@classmethod

def __subclasshook__(cls,other):

quack = getattr(other,'quack',None)

return callable(quack)

class Duck(object):

def quack(self):

pass

print(issubclass(Duck,AbstractDuck))

class NotDuck(object):

quack = 'foo'

AbstractDuck.register(NotDuck) #当__subclasshook__被定义时,优先级大于register

print(issubclass(NotDuck,AbstractDuck))

# 以上展示抽象基类是如何使一个类能够声明它自身可以通过类型检查测试

# 其他现有方法#######################################################

# 1.使用NotImplementedError

from datetime import datetime

class Task(object):

def __init__(self):

self.runs = []

def run(self):

start = datetime.now()

result = self._run()

end = datetime.now()

self.runs.append({'start':start,

'end':end,

'result':result})

return result

def _run(self):

raise NotImplementedError('Task subclasses must define a _run method')

t = Task()

# t.run()

# 2.使用元类

class TaskMeta(type):

def __new__(cls,name,bases,attrs):

if attrs.pop('abstract',False):

return super(TaskMeta, cls).__new__(cls,name,bases,attrs)

new_class = super(TaskMeta, cls).__new__(cls,name,bases,attrs)

if not hasattr(new_class,'_run') or not callable(new_class._run):

raise TypeError('Task subclass must define _run method')

return new_class

class Task1(metaclass=TaskMeta):

abstract = True

pass

Task1()

# 抽象基类的价值

class Task3(metaclass=abc.ABCMeta):

def __init__(self):

self.runs = []

def run(self):

start = datetime.now()

result = self._run()

end = datetime.now()

self.runs.append({'start':start,

'end':end,

'result':result})

return result

@abc.abstractmethod

def _run(self):

pass

class SubTask(Task3):

pass

# 无法实例化

# SubTask()

class OtherTask(Task3):

def _run(self):

return 2

OtherTask().run()

# 抽象属性

class AbstractClass(metaclass=abc.ABCMeta):

@property

@abc.abstractproperty

def foo(self):

pass

# 抽象类或静态方法

class AbstractClass1(metaclass=abc.ABCMeta):

@classmethod

@abc.abstractmethod

def foo(cls):

return 42

class SubC(AbstractClass1):

pass

print(SubC.foo())

# SubC不能实例化

# 内置抽象基类

from collections.abc import *

Callable(__call__)

Container(__contains__)

Hashable(__hash__)

Iterable(__iter__)

Sized(__len__)

  • 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、付费专栏及课程。

余额充值