如何在Python中的命名元组中强制变量类型?

问题描述 投票:0回答:2

我正在遵循这个关于命名元组的教程,并指定变量类型。但是,我修改了代码(如下),即使我输入了错误类型的值,也没有出现错误消息或编程中断。我知道您可以编写自己的 try/ except 来引发错误异常,但是是否有现成的解决方案/语法来强制用户输入正确类型的变量。

from typing import NamedTuple

class Pet(NamedTuple):
    pet_name: str
    pet_type: str

    def __repr__(self):
        return f"{self.pet_name}, {self.pet_type}"

cleons_pet = Pet('Cotton', 'owl')
print('cleons_pet: ', cleons_pet)

cleons_pet_v2 = Pet(222, 1)
print('cleons_pet_v2: ', cleons_pet_v2)

# Output
cleons_pet:  Cotton, owl
cleons_pet_v2:  222, 1
[Finished in 0.1s]
python-3.x typing namedtuple
2个回答
3
投票

python 中的类型提示不会被 python 本身计算!请参阅PEP484

虽然这些注释可在运行时通过通常的 annotations 属性使用,但运行时不会发生类型检查。相反,该提案假设存在一个单独的离线类型检查器,用户可以自愿运行其源代码。

至少有两个项目提供离线类型检查(mypypyre)。如果您在项目中使用类型提示,那么您绝对应该使用它们。

如果您想在运行应用程序时验证输入,您必须通过自己验证数据来说服离线类型检查器或使用第三方库。我知道 attrs,您可以在其中使用 validators类型注释 进行在线验证。


0
投票

由于 NamedTuple 不允许覆盖 newinit,因此无法在实例创建期间执行验证。为了解决这个约束,我向我的 NamedTuple 类添加了一个通用验证方法,并在创建实例后调用它 -

def validate_namedtuple_types(self):
for field, annotation in self.__annotations__.items():
    if not isinstance(getattr(self, field), annotation):
        raise TypeError(f'provided value "{getattr(self, field)}" is wrong type ' + \
                        f'({type(getattr(self, field))}) for field {field} (should be {annotation})')

这可以直接添加到 NamedTyple 类中或作为外部函数引用,例如

class Ethernet(NamedTuple):
dst_addr: EthAddr | str
src_addr: EthAddr
type:     int     = 0x86DD
validate_types = validate_namedtuple_types
© www.soinside.com 2019 - 2024. All rights reserved.