Qwen/lib/python3.12/abc.py
class abstractstaticmethod(staticmethod):
"""A decorator indicating abstract staticmethods.
Deprecated, use 'staticmethod' with 'abstractmethod' instead:
class C(ABC):
@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):
...
"""
__isabstractmethod__ = True
def __init__(self, callable):
callable.__isabstractmethod__ = True
super().__init__(callable)
class abstractproperty(property):
"""A decorator indicating abstract properties.
Deprecated, use 'property' with 'abstractmethod' instead:
class C(ABC):
@property
@abstractmethod
def my_abstract_property(self):
...
"""
__isabstractmethod__ = True
try:
from _abc import (get_cache_token, _abc_init, _abc_register,
_abc_instancecheck, _abc_subclasscheck, _get_dump,
_reset_registry, _reset_caches)
except ImportError:
from _py_abc import ABCMeta, get_cache_token
ABCMeta.__module__ = 'abc'
else:
class ABCMeta(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()).
"""
def __new__(mcls, name, bases, namespace, /, **kwargs):
cls = super().__new__(mcls, name, bases, namespace, **kwargs)
_abc_init(cls)
return cls
def register(cls, subclass):
"""Register a virtual subclass of an ABC.
Returns the subclass, to allow usage as a class decorator.
"""
return _abc_register(cls, subclass)
def __instancecheck__(cls, instance):
"""Override for isinstance(instance, cls)."""
return _abc_instancecheck(cls, instance)
def __subclasscheck__(cls, subclass):
"""Override for issubclass(subclass, cls)."""
return _abc_subclasscheck(cls, subclass)
def _dump_registry(cls, file=None):
"""Debug helper to print the ABC registry."""
print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
print(f"Inv. counter: {get_cache_token()}", file=file)
(_abc_registry, _abc_cache, _abc_negative_cache,
_abc_negative_cache_version) = _get_dump(cls)
print(f"_abc_registry: {_abc_registry!r}", file=file)
print(f"_abc_cache: {_abc_cache!r}", file=file)
print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file)
print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}",
file=file)
def _abc_registry_clear(cls):
"""Clear the registry (for debugging or testing)."""
_reset_registry(cls)
def _abc_caches_clear(cls):
"""Clear the caches (for debugging or testing)."""
_reset_caches(cls)
def update_abstractmethods(cls):
"""Recalculate the set of abstract methods of an abstract class.
If a class has had one of its abstract methods implemented after the
class was created, the method will not be considered implemented until
this function is called. Alternatively, if a new abstract method has been
added to the class, it will only be considered an abstract method of the
class after this function is called.
This function should be called before any use is made of the class,
usually in class decorators that add methods to the subject class.
Returns cls, to allow usage as a class decorator.
If cls is not an instance of ABCMeta, does nothing.
"""
if not hasattr(cls, '__abstractmethods__'):
# We check for __abstractmethods__ here because cls might by a C
# implementation or a python implementation (especially during
# testing), and we want to handle both cases.
return cls
abstracts = set()
# Check the existing abstract methods of the parents, keep only the ones
# that are not implemented.
for scls in cls.__bases__:
for name in getattr(scls, '__abstractmethods__', ()):
value = getattr(cls, name, None)
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
# Also add any other newly added abstract methods.
for name, value in cls.__dict__.items():
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
cls.__abstractmethods__ = frozenset(abstracts)
return cls
class ABC(metaclass=ABCMeta):
"""Helper class that provides a standard way to create an ABC using
inheritance.
"""
__slots__ = ()
abc.py
是 Python 的标准库模块之一,用于定义抽象基类(Abstract Base Classes,简称 ABCs)。抽象基类提供了一种机制,可以定义接口并强制子类实现这些接口。下面是代码的逐行解释:
abstractstaticmethod
类
python
复制
class abstractstaticmethod(staticmethod):
"""A decorator indicating abstract staticmethods.
Deprecated, use 'staticmethod' with 'abstractmethod' instead:
class C(ABC):
@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):
...
"""
这是一个装饰器类,用于指示抽象静态方法。
已废弃,建议使用 staticmethod
与 abstractmethod
组合代替。
python
复制
__isabstractmethod__ = True
设置一个类属性,表明这是一个抽象方法。
python
复制
def __init__(self, callable):
callable.__isabstractmethod__ = True
super().__init__(callable)
初始化方法,接受一个可调用对象,并将其标记为抽象方法。
abstractproperty
类
python
复制
class abstractproperty(property):
"""A decorator indicating abstract properties.
Deprecated, use 'property' with 'abstractmethod' instead:
class C(ABC):
@property
@abstractmethod
def my_abstract_property(self):
...
"""
这是一个装饰器类,用于指示抽象属性。
已废弃,建议使用 property
与 abstractmethod
组合代替。
python
复制
__isabstractmethod__ = True
设置一个类属性,表明这是一个抽象方法。
导入 _abc
模块
python
复制
try:
from _abc import (get_cache_token, _abc_init, _abc_register,
_abc_instancecheck, _abc_subclasscheck, _get_dump,
_reset_registry, _reset_caches)
except ImportError:
from _py_abc import ABCMeta, get_cache_token
ABCMeta.__module__ = 'abc'
尝试导入 _abc
模块中的各种方法。
如果导入失败,回退到 _py_abc
模块,并导入 ABCMeta
和 get_cache_token
。
ABCMeta
类
python
复制
else:
class ABCMeta(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()).
"""
ABCMeta
是一个元类,用于定义抽象基类。
使用这个元类可以创建一个 ABC,可以直接子类化或作为混入类使用。
python
复制
def __new__(mcls, name, bases, namespace, /, **kwargs):
cls = super().__new__(mcls, name, bases, namespace, **kwargs)
_abc_init(cls)
return cls
__new__
方法用于创建类对象,并初始化 ABC 相关属性。
python
复制
def register(cls, subclass):
"""Register a virtual subclass of an ABC.
Returns the subclass, to allow usage as a class decorator.
"""
return _abc_register(cls, subclass)
register
方法用于注册虚拟子类。
python
复制
def __instancecheck__(cls, instance):
"""Override for isinstance(instance, cls)."""
return _abc_instancecheck(cls, instance)
__instancecheck__
方法用于重载 isinstance
检查。
python
复制
def __subclasscheck__(cls, subclass):
"""Override for issubclass(subclass, cls)."""
return _abc_subclasscheck(cls, subclass)
__subclasscheck__
方法用于重载 issubclass
检查。
python
复制
def _dump_registry(cls, file=None):
"""Debug helper to print the ABC registry."""
print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
print(f"Inv. counter: {get_cache_token()}", file=file)
(_abc_registry, _abc_cache, _abc_negative_cache,
_abc_negative_cache_version) = _get_dump(cls)
print(f"_abc_registry: {_abc_registry!r}", file=file)
print(f"_abc_cache: {_abc_cache!r}", file=file)
print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file)
print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}",
file=file)
_dump_registry
方法用于打印 ABC 注册表,帮助调试。
python
复制
def _abc_registry_clear(cls):
"""Clear the registry (for debugging or testing)."""
_reset_registry(cls)
_abc_registry_clear
方法用于清除注册表。
python
复制
def _abc_caches_clear(cls):
"""Clear the caches (for debugging or testing)."""
_reset_caches(cls)
_abc_caches_clear
方法用于清除缓存。
update_abstractmethods
方法
python
复制
def update_abstractmethods(cls):
"""Recalculate the set of abstract methods of an abstract class.
If a class has had one of its abstract methods implemented after the
class was created, the method will not be considered implemented until
this function is called. Alternatively, if a new abstract method has been
added to the class, it will only be considered an abstract method of the
class after this function is called.
This function should be called before any use is made of the class,
usually in class decorators that add methods to the subject class.
Returns cls, to allow usage as a class decorator.
If cls is not an instance of ABCMeta, does nothing.
"""
update_abstractmethods
函数用于重新计算抽象类的抽象方法集合。
python
复制
if not hasattr(cls, '__abstractmethods__'):
# We check for __abstractmethods__ here because cls might by a C
# implementation or a python implementation (especially during
# testing), and we want to handle both cases.
return cls
检查类是否具有 __abstractmethods__
属性,如果没有,则返回类本身。
python
复制
abstracts = set()
# Check the existing abstract methods of the parents, keep only the ones
# that are not implemented.
for scls in cls.__bases__:
for name in getattr(scls, '__abstractmethods__', ()):
value = getattr(cls, name, None)
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
# Also add any other newly added abstract methods.
for name, value in cls.__dict__.items():
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
cls.__abstractmethods__ = frozenset(abstracts)
return cls
检查父类的抽象方法,将未实现的方法保留在集合中。
检查当前类的新抽象方法,并将其添加到集合中。
更新类的 __abstractmethods__
属性并返回类。
ABC
类
python
复制
class ABC(metaclass=ABCMeta):
"""Helper class that provides a standard way to create an ABC using
inheritance.
"""
__slots__ = ()
ABC
类是一个帮助类,提供了一种标准方式来创建 ABC。
使用 ABCMeta
作为元类。
__slots__
属性为空,表示该类不允许动态添加属性。
ABC
类(续)
python
复制
class ABC(metaclass=ABCMeta):
"""Helper class that provides a standard way to create an ABC using
inheritance.
"""
__slots__ = ()
ABC
类是一个帮助类,提供了一种标准方式来创建抽象基类。
使用 ABCMeta
作为元类。
__slots__
属性为空,表示该类不允许动态添加属性。
总结
这个 abc.py
模块主要用于定义和管理抽象基类(ABCs)和抽象方法。以下是各部分的功能总结:
abstractstaticmethod
和 abstractproperty
类:
staticmethod
和 abstractmethod
的组合。
ABCMeta
元类:
register
、__instancecheck__
、__subclasscheck__
、_dump_registry
、_abc_registry_clear
和 _abc_caches_clear
。
update_abstractmethods
函数:
ABC
类:
ABCMeta
作为其元类,并且通过 __slots__
属性限制动态属性的添加。
通过这些工具,abc.py
模块提供了一种标准化的方式来定义和管理抽象基类及其方法,从而增强了代码的结构性和可维护性。
总结
### 文章总结:`abc.py` 模块概述`abc.py` 是 Python 标准库中的一个重要模块,专门用于定义和管理抽象基类(Abstract Base Classes, ABCs)及其抽象方法。该模块通过一系列类、装饰器和函数,提供了一种标准化的方式强制子类实现特定的接口,提高了代码的结构性和可维护性。
#### 主要组成部分及其功能:
1. **废弃的装饰器类**:
- **`abstractstaticmethod` 和 `abstractproperty`:**
- 这两个类用作装饰器,分别指示抽象静态方法和抽象属性。然而,它们已经被废弃,现在推荐使用 `staticmethod` 搭配 `abstractmethod` 和 `property` 搭配 `abstractmethod` 的组合方式。
2. **`ABCMeta` 元类:**
- **用途:** 定义抽象基类的元类。通过继承此元类,可以创建包含抽象方法的类,并强制子类实现这些抽象方法。
- **核心方法:**
- `__new__`:构造函数,用于初始化 ABC 相关属性。
- `register`:用于注册 ABC 的虚拟子类,使即便是非直接子类关系的类也能被视作子类。
- `__instancecheck__` 和 `__subclasscheck__`:重载这两个魔法方法以支持实例和子类的检查,适应 ABC 的特殊逻辑。
- `_dump_registry`:调试助手,用于打印 ABC 注册表信息。
- `_abc_registry_clear` 和 `_abc_caches_clear`:用于清除注册表和缓存的方法,主要在调试或测试中使用。
3. **`update_abstractmethods` 函数:**
- 功能:重新计算给定抽象类的抽象方法集合。如果在类创建后实施了抽象方法或添加了新的抽象方法,需调用此函数以更新集合。
- 使用场景:通常在通过类装饰器向类中添加方法的情况下调用。
4. **`ABC` 类**:
- 这是一个帮助类,提供了一个方便的途径来创建 ABC。它使用 `ABCMeta` 作为其元类,并通过设置 `__slots__` 为空(不允许动态添加属性)来增强类的封装性。
#### 总结:
`abc.py` 模块通过提供标准化的工具,包括装饰器(尽管部分已废弃)、元类和函数,有效地支持了抽象基类及其方法的定义和管理。这不仅增强了代码的结构性和可维护性,还为大型项目中的接口设计和代码复用提供了坚实的基础。无论是对于面向对象设计原则的贯彻,还是对于提升团队协作效率,`abc.py` 模块都扮演着不可或缺的角色。