python抽象基类都有哪些_Python之抽象基类

classABCMeta(type):"""Metaclass for defining Abstract Base Classes (ABCs).

Use this metaclass to create an ABC. An ABC can be subclassed

directly, and then acts as a mix-in class. You can also register

unrelated concrete classes (even built-in classes) and unrelated

ABCs as 'virtual subclasses' -- these and their descendants will

be considered subclasses of the registering ABC by the built-in

issubclass() function, but the registering ABC won't show up in

their MRO (Method Resolution Order) nor will method

implementations defined by the registering ABC be callable (not

even via super())."""

#A global counter that is incremented each time a class is

#registered as a virtual subclass of anything. It forces the

#negative cache to be cleared before its next use.

#Note: this counter is private. Use `abc.get_cache_token()` for

#external code.

_abc_invalidation_counter =0def __new__(mcls, name, bases, namespace):

cls= super().__new__(mcls, name, bases, namespace)#Compute set of abstract method names

abstracts ={namefor name, value innamespace.items()if getattr(value, "__isabstractmethod__", False)}for base inbases:for name in getattr(base, "__abstractmethods__", set()):

value=getattr(cls, name, None)if getattr(value, "__isabstractmethod__", False):

abstracts.add(name)

cls.__abstractmethods__ =frozenset(abstracts)#Set up inheritance registry

cls._abc_registry =WeakSet()

cls._abc_cache=WeakSet()

cls._abc_negative_cache=WeakSet()

cls._abc_negative_cache_version=ABCMeta._abc_invalidation_counterreturnclsdefregister(cls, subclass):"""Register a virtual subclass of an ABC.

Returns the subclass, to allow usage as a class decorator."""

if notisinstance(subclass, type):raise TypeError("Can only register classes")ifissubclass(subclass, cls):return subclass #Already a subclass

#Subtle: test for cycles *after* testing for "already a subclass";

#this means we allow X.register(X) and interpret it as a no-op.

ifissubclass(cls, subclass):#This would create a cycle, which is bad for the algorithm below

raise RuntimeError("Refusing to create an inheritance cycle")

cls._abc_registry.add(subclass)

ABCMeta._abc_invalidation_counter+= 1 #Invalidate negative cache

returnsubclassdef _dump_registry(cls, file=None):"""Debug helper to print the ABC registry."""

print("Class: %s.%s" % (cls.__module__, cls.__qualname__), file=file)print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file)for name in sorted(cls.__dict__.keys()):if name.startswith("_abc_"):

value=getattr(cls, name)print("%s: %r" % (name, value), file=file)def __instancecheck__(cls, instance):"""Override for isinstance(instance, cls)."""

#Inline the cache checking

subclass = instance.__class__

if subclass incls._abc_cache:returnTrue

subtype=type(instance)if subtype issubclass:if (cls._abc_negative_cache_version ==ABCMeta._abc_invalidation_counterandsubclassincls._abc_negative_cache):returnFalse#Fall back to the subclass check.

return cls.__subclasscheck__(subclass)return any(cls.__subclasscheck__(c) for c in{subclass, subtype})def __subclasscheck__(cls, subclass):"""Override for issubclass(subclass, cls)."""

#Check cache

if subclass incls._abc_cache:returnTrue#Check negative cache; may have to invalidate

if cls._abc_negative_cache_version

cls._abc_negative_cache =WeakSet()

cls._abc_negative_cache_version=ABCMeta._abc_invalidation_counterelif subclass incls._abc_negative_cache:returnFalse#Check the subclass hook

ok = cls.__subclasshook__(subclass)if ok is notNotImplemented:assertisinstance(ok, bool)ifok:

cls._abc_cache.add(subclass)else:

cls._abc_negative_cache.add(subclass)returnok#Check if it's a direct subclass

if cls in getattr(subclass, '__mro__', ()):

cls._abc_cache.add(subclass)returnTrue#Check if it's a subclass of a registered class (recursive)

for rcls incls._abc_registry:ifissubclass(subclass, rcls):

cls._abc_cache.add(subclass)returnTrue#Check if it's a subclass of a subclass (recursive)

for scls in cls.__subclasses__():ifissubclass(subclass, scls):

cls._abc_cache.add(subclass)returnTrue#No dice; update negative cache

cls._abc_negative_cache.add(subclass)returnFalseclass ABC(metaclass=ABCMeta):"""Helper class that provides a standard way to create an ABC using

inheritance."""

pass

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值