擅长:python、mysql、java
<p>您可以使用新的in Python 3.6 <code>__init_subclass__</code>功能。<br/>
这是一个在基类上定义的classmethod,在创建时将为创建的每个子类调用一次。对于大多数断言用例来说,它可能比Python的ABC更有用,后者只会在类实例化时引发错误(相反,如果您想在进入具体类之前对其他AbstrateClass进行子类化,则必须在代码中检查这一点)。你知道吗</p>
<p>因此,例如,如果要通过在基类上做注释来指示子类上所需的方法和属性,可以执行以下操作:</p>
<pre class="lang-py prettyprint-override"><code>_sentinel = type("_", (), {})
class Base:
def __init_subclass__(cls, **kwargs):
errors = []
for attr_name, type_ in cls.__annotations__.items():
if not isinstance(getattr(cls, attr_name, _sentinel), type_):
errors.append((attr_name, type))
if errors:
raise TypeError(f"Class {cls.__name__} failed to initialize the following attributes: {errors}")
super().__init_subclass__(**kwargs)
s: int
class B(Base):
pass
</code></pre>
<p>您可以将<code>collections.abc.Callable</code>放在需要方法的注释上,或者将<code>(type(None), int)</code>这样的元组放在可选整数上,但是<code>isinstance</code>不幸的是,无法使用“typing”模块提供的多功能语义。如果您需要,我建议您看看<a href="https://pydantic-docs.helpmanual.io/" rel="nofollow noreferrer">pydantic</a>项目并加以利用。你知道吗</p>