Python类中无法访问动态生成的getter/setter函数问题求助
我来帮你解决这个问题!你遇到的AttributeError主要是因为动态添加方法的方式不对,或者生成的方法没有正确绑定到类/实例上。咱们一步步来理清楚:
问题根源
- 如果你直接把生成的函数塞进实例的
__dict__里,这些函数只是普通函数,不会被自动绑定为实例方法(也就是调用时不会自动传入self参数);更关键的是,如果遍历逻辑有问题,可能根本没把函数正确添加到属性字典中。 - 另外,如果你想让所有类实例都能调用这些getter/setter,应该把方法添加到类的命名空间,而不是单个实例的
__dict__。
修正后的完整代码
import operator from functools import reduce class MyClass: def __init__(self): self.dictionary = { "a": { "b": 1, "c": 2 }, "d": { "e": { "f": 3, "g": 4 } } } self.add_getters_setters() def add_getters_setters(self): # 递归遍历嵌套字典,记录每个键的完整路径 def traverse(current_path, current_data): if isinstance(current_data, dict): for key, value in current_data.items(): traverse(current_path + [key], value) else: # 生成驼峰式的方法名,比如路径["a","b"]→getAB/setAB capitalized_keys = [key.capitalize() for key in current_path] getter_name = f"get{''.join(capitalized_keys)}" setter_name = f"set{''.join(capitalized_keys)}" # 定义getter函数:根据路径获取嵌套字典的值 def getter(self): return reduce(operator.getitem, current_path, self.dictionary) # 定义setter函数:修改嵌套字典对应路径的值 def setter(self, value): parent_dict = reduce(operator.getitem, current_path[:-1], self.dictionary) parent_dict[current_path[-1]] = value # 把方法绑定到类上,所有实例都能共享调用 setattr(self.__class__, getter_name, getter) setattr(self.__class__, setter_name, setter) # 从根字典开始遍历生成方法 traverse([], self.dictionary) # 测试验证 if __name__ == "__main__": obj = MyClass() print(obj.getAB()) # 输出1 obj.setAB(100) print(obj.getAB()) # 输出100 print(obj.getDEF()) # 输出3 obj.setDEF(200) print(obj.getDEF()) # 输出200
关键说明
- 用
setattr绑定到类:通过self.__class__获取当前类,再用setattr把生成的函数添加为类方法,这样所有实例都能继承这些方法,而且调用时self会被自动传入。 - 递归遍历生成路径:深度优先遍历嵌套字典,记录每个值的完整键路径,以此生成符合习惯的驼峰式方法名。
- 高效操作嵌套字典:用
reduce(operator.getitem, path, self.dictionary)快速定位嵌套字典中的值;设置值时先拿到父级字典,再修改目标键,避免多层索引的繁琐。
仅给单个实例添加方法的方案
如果你不想让所有实例都拥有这些方法,只想给当前创建的实例添加,可以用types.MethodType把函数绑定到实例:
import types # 在traverse函数的else块中,替换setattr代码为: self.__dict__[getter_name] = types.MethodType(getter, self) self.__dict__[setter_name] = types.MethodType(setter, self)
这样生成的方法仅属于当前实例,其他MyClass实例不会拥有这些方法。
内容的提问来源于stack exchange,提问作者Clayton Ramstedt
相关产品推荐
相关产品推荐

