我可以在 Python 3.6 中编写 abc.ABC 而不求助于元类吗?
Can I write abc.ABC without resorting to metaclasses in Python 3.6?
Python 3.6 added PEP 487, which adds an __init_subclass__
method among other things. Is it possible to write a version of ABC
不使用元类?
如果您只关心抽象方法的检查,那么是的。只需将 abstract method set computation 移动到 __init_subclass__
方法:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
# Compute set of abstract method names
abstracts = {name
for name, value in vars(cls).items()
if getattr(value, "__isabstractmethod__", False)}
for base in cls.__bases__:
for name in getattr(base, "__abstractmethods__", set()):
value = getattr(cls, name, None)
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
cls.__abstractmethods__ = frozenset(abstracts)
基础 object.__new__
implementation 然后使用非空 __abstractmethods__
集来防止实例化。
但是ABCs也支持virtual subclass registration; the two hook methods this requires有在元类上实现
Python 3.6 added PEP 487, which adds an __init_subclass__
method among other things. Is it possible to write a version of ABC
不使用元类?
如果您只关心抽象方法的检查,那么是的。只需将 abstract method set computation 移动到 __init_subclass__
方法:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
# Compute set of abstract method names
abstracts = {name
for name, value in vars(cls).items()
if getattr(value, "__isabstractmethod__", False)}
for base in cls.__bases__:
for name in getattr(base, "__abstractmethods__", set()):
value = getattr(cls, name, None)
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
cls.__abstractmethods__ = frozenset(abstracts)
基础 object.__new__
implementation 然后使用非空 __abstractmethods__
集来防止实例化。
但是ABCs也支持virtual subclass registration; the two hook methods this requires有在元类上实现