如何在Python中通过用户输入变量修改类类型属性的value值?
解决动态嵌套访问/修改Python对象属性的问题
嘿,我明白你现在的困扰——用eval嵌套访问属性时踩坑了对吧?其实问题出在eval(var1).eval(var2)这个写法上:eval(var1)拿到的是你的Create实例(比如示例里的a),但这个实例本身根本没有eval方法,自然会报AttributeError。咱们换个更靠谱的方式来实现这个需求,而且比用eval更安全。
先理清楚你的类结构(我稍微调整了类名和变量名,尽量符合Python的PEP8规范,看起来更舒服):
class Setting: def __init__(self, name, value, is_required): self.name = name self.value = value self.IsRequired = is_required # 这里其实建议改成小驼峰is_required,更符合Python编码规范 class Create: def __init__(self, name): self.name = name # 初始化两个Setting实例作为实例属性 self.filter = Setting("filter_config", "default_val", True) self.consumer = Setting("consumer_config", "default_consumer", False)
最直接的解决方案:用getattr()逐层获取属性
你的需求是通过两个字符串(比如var1="a"是对象名,var2="filter"是属性名)来修改对应Setting实例的value,完全可以用Python内置的getattr()函数来实现,步骤很清晰:
# 先创建一个Create实例 a = Create("test_instance") # 模拟用户输入的字符串 var1 = "a" var2 = "filter" # 1. 获取目标对象(用globals()比eval更安全,避免恶意代码风险) target_obj = globals()[var1] # 2. 获取对象的指定属性(这里就是filter对应的Setting实例) setting_inst = getattr(target_obj, var2) # 3. 修改value属性 setting_inst.value = "UpdatedValue" # 验证修改结果 print(a.filter.value) # 输出: UpdatedValue
为什么不推荐用eval嵌套?
你之前尝试的eval(var1).eval(var2)逻辑完全错了——eval(var1)返回的是Create实例,而这个实例并没有eval方法,相当于你在调用a.eval("filter"),这肯定不存在啊!而且eval本身有安全风险,如果用户输入恶意字符串,可能会执行危险代码,所以能不用就尽量不用。
进阶:处理更深层次的嵌套属性
如果以后需要处理更复杂的嵌套路径(比如字符串是"filter.IsRequired"),可以写个小工具函数来逐层解析:
def get_nested_attr(obj, attr_path): """根据点分隔的属性路径,逐层获取对象属性""" attrs = attr_path.split(".") current_obj = obj for attr in attrs: current_obj = getattr(current_obj, attr) return current_obj def set_nested_attr(obj, attr_path, new_value): """根据点分隔的属性路径,修改对象的嵌套属性""" attrs = attr_path.split(".") # 获取到最后一层属性的父对象 parent_obj = get_nested_attr(obj, ".".join(attrs[:-1])) if len(attrs) > 1 else obj # 修改最后一层属性 setattr(parent_obj, attrs[-1], new_value) # 使用示例 var3 = "filter.IsRequired" # 获取嵌套属性值 is_required = get_nested_attr(globals()[var1], var3) print(is_required) # 输出: True # 修改嵌套属性 set_nested_attr(globals()[var1], "filter.value", "DeepUpdatedValue") print(a.filter.value) # 输出: DeepUpdatedValue
这样不管属性嵌套多少层,都能轻松处理,而且全程不用eval,安全又可靠。
内容的提问来源于stack exchange,提问作者Nathan Grosse
相关产品推荐
相关产品推荐

