<p>很好的建议,但我观察到它比所有这些都简单得多@亚历克斯·韦古德(alex waygood)有一些很好的解释,即使像我一样,你发现他的解决方案有点过火,他的答案也更正确</p>
<pre><code>class HomebrewTypeGuarding:
""""Class mimics the primary interface of a dict, as an example
of naive guarding using the __annotations__ collection that
exists on any type-annotated object.
"""
a: str
b: int
def __getitem__(self, key):
return (
self.__dict__[key]
if key in self.__dict__
else None
)
def __setitem__(self, key, value):
if (
key in self.__annotations__
and isinstance(value, self.__annotations__[key])
):
self.__dict__[key] = value
else:
raise ValueError(
"Incorrect type for value on {}:{} = {}".format(
key,
str(
self.__annotations__[key]
if key in self.__annotations__
else None
),
str(value)
)
)
</code></pre>
<p>这里的管道要简单得多,但请注意,我并不是说这是一个命令。我的意图是</p>
<ol>
<li>使用<strong>注释<strong>集合简单演示类型保护,以及</li>
<li>这样做的方式可以远远超出口述</李>
</ol>
<p>如果你真的只是在读一篇经过打字检查的口述,那么,@alex waygood将在这里详细介绍,他的解决方案实际上是完整和正确的</p>
<p>如果您对运行时类型检查更感兴趣,在属性或属性分配时,我相信这个解决方案是优越的,因为它实际上可以可靠地发生,对于许多类型,更正确和完整的选项是A,将被复制粘贴到您的所有用例实现中,或者B,转换为元类或装饰器,修改getitem和setitem dunders,成为下面的某种形式</p>
<p>注意,对于B,许多可能的用例具有不同的需求@s-m-e指定了dict,它不能直接用作dict的包装器/装饰器,但可以很容易地进行调整。我更希望您为此调用修饰类/实例上的原始getitem/setitem dunders,而不是直接修改<code>self.__dict__</code>或<code>self</code>集合。我想要的是使用annotations对象进行类型检查的最简单示例。如果编写安装(或重写)getitem/setitem对的类或实例修饰符,并且如果这些Dunder只是读取/修改<code>self.__dict__</code>,则会中断DICT。如果您遵守此免责声明,并写出<code>super().__getitem__(in_key)</code>,那么对于继承遍历的常见问题,第一代类(例如,此类装饰器的某些实现仍然失败)和多重继承存在边缘情况。当您解决这个问题时,您几乎肯定在类型上使用了getattrs,并为相关的<code>__getitem__</code>和<code>__setitem__</code>方法或属性探索了多个并行路径</p>