为何无法向isinstance()动态传入类型?代码报错求助
我尝试从对象中获取数据类型,并在isinstance()中与变量进行比较。示例代码如下(BaseModel来自pydantic):
from pydantic import BaseModel class ColSchema(BaseModel): display: str internal: str data_type: str schema = [ ColSchema(display="Status", internal="status", data_type="str"), ColSchema(display="Mobile Number", internal="mobile_number", data_type="str"), ColSchema(display="DPD", internal="dpd", data_type="float") ] for item in schema: if isinstance(variable, item.data_type): return True else: return False
运行时触发报错:TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union。请问我哪里出错了?使用type(...)==type(...)可以实现需求,但我的代码检查工具(linter)对此表示不满。
错误原因
你传入isinstance()的第二个参数是字符串字面量(比如"str"、"float"),但isinstance()要求第二个参数必须是类型对象(比如str、float这类原生类型,或自定义类),字符串不属于合法参数类型,因此触发报错。
解决方法
方法1:直接存储类型对象(推荐)
修改ColSchema的data_type字段类型,让它存储类型对象而非字符串,这样可以直接在isinstance()中使用:
from pydantic import BaseModel class ColSchema(BaseModel): display: str internal: str data_type: type # 改为type类型 schema = [ ColSchema(display="Status", internal="status", data_type=str), ColSchema(display="Mobile Number", internal="mobile_number", data_type=str), ColSchema(display="DPD", internal="dpd", data_type=float) ] # 类型检查示例 def check_variable_type(variable): for item in schema: if isinstance(variable, item.data_type): return True return False
方法2:建立字符串到类型的映射字典(适用于必须保留字符串类型标识的场景)
如果因为业务需求(比如从配置文件读取类型字符串)必须保留data_type的字符串格式,可以创建映射字典,将字符串转换为对应的类型对象:
from pydantic import BaseModel class ColSchema(BaseModel): display: str internal: str data_type: str # 定义字符串到类型的映射 TYPE_MAP = { "str": str, "float": float, "int": int, # 可根据需求扩展更多类型 } schema = [ ColSchema(display="Status", internal="status", data_type="str"), ColSchema(display="Mobile Number", internal="mobile_number", data_type="str"), ColSchema(display="DPD", internal="dpd", data_type="float") ] # 类型检查示例 def check_variable_type(variable): for item in schema: target_type = TYPE_MAP.get(item.data_type) if target_type and isinstance(variable, target_type): return True return False
为什么linter不推荐type(...) == type(...)
type(variable) == type(target)只能判断变量类型是否与目标类型完全一致,无法处理继承关系。比如自定义子类MyStr(str),type(MyStr()) == str会返回False,但isinstance(MyStr(), str)会返回True,后者更符合Python多态设计的严谨性,因此linter会推荐使用isinstance()做类型检查。
内容的提问来源于stack exchange,提问作者Shourya Dwivedi

