自定义Variable类调用getattr报错,如何解决属性名类型校验问题?
问题原因
你遇到的问题根源在于,Python内置函数getattr的底层实现会直接检查第二个参数的底层类型是否为字符串(PyUnicode_Type),而非通过isinstance的逻辑判断。你修改__class__属性只是让isinstance返回True,但并没有改变对象的实际底层类型(依然是Variable类的实例),所以getattr的类型检查还是会失败。
解决方案
方案1:让Variable继承自str
让Variable成为str的子类,这样它的底层类型会被getattr识别为字符串类型,同时通过额外的可变存储实现值的可修改特性:
from typing import Any class Variable(str): def __new__(cls, value): # 初始化str父类的内容 return super().__new__(cls, value) def __init__(self, value) -> None: # 用列表存储可变值(列表是可变容器) self.storage = [value] @property def value(self) -> Any: return self.storage[0] @value.setter def value(self, value) -> None: # 可保留你原来的_get_value逻辑 self.storage[0] = value def get(self) -> Any: return self.value def set(self, value) -> None: self.value = value # 重写操作符,让它们作用于可变的value而非父类str的不可变内容 def __iadd__(self, other): self.value += other return self def __eq__(self, other): return self.value == other
修改后,getattr(obj, Variable("attr"))可以正常执行,同时你依然能通过value属性修改包装的值。
方案2:显式转换为字符串
如果不想修改类的继承关系,在调用getattr时显式将Variable实例转换为字符串即可:
var = Variable("attr") getattr(obj, str(var)) # 显式调用str()完成类型转换
内容的提问来源于stack exchange,提问作者Zhiyuan Chen
相关产品推荐
相关产品推荐

