Python类构造函数循环创建属性后无法访问属性的问题求助
解决动态添加属性后无法访问的问题
让我来帮你排查代码里的几个关键问题,搞定这个动态属性访问的麻烦:
问题1:__setattr__方法写偏了
你重写的__setattr__里,不管传入的属性名是什么,都硬编码去设置myattrib这个属性,这就导致所有动态处理后的属性名根本没被真正绑定到实例上。正确的做法是用方法参数里的prop来指定要设置的属性:
def __setattr__(self, prop, val): super().__setattr__(prop, val) # 用传入的prop替代固定的'myattrib' print(f"setting {prop}")
问题2:调用__setattr__时多传了参数
在__init__里,你写的self.__setattr__(self, item, 'hi')多传了一个self——因为当通过实例调用方法时,Python会自动把实例作为第一个参数(也就是self)传入,所以正确的调用应该是:
self.__setattr__(item, 'hi')
问题3:混淆了类属性和实例属性
你最后尝试访问NewClass.url,但这些动态添加的属性是绑定在实例上的,不是类本身的属性。必须先创建类的实例,再访问实例的属性:
obj = NewClass() print(obj.url)
修正后的完整代码
这里给你两种方案,看你是否需要自定义属性设置的日志逻辑:
方案1:保留自定义__setattr__的打印逻辑
starting_list = ["Company", "Contact Name", "Email", "Phone", "URL", "Country", "Source"] class NewClass(object): def __setattr__(self, prop, val): super().__setattr__(prop, val) print(f"setting {prop}") def __init__(self): for item in starting_list: # 属性名清理逻辑保留 item = str(item).lower().strip().replace(' ', '_') self.__setattr__(item, 'hi') print(item) # 创建实例后访问属性 obj = NewClass() print(obj.url)
方案2:更简洁的实现(无需重写__setattr__)
如果只是要动态添加属性,不需要额外的打印逻辑,直接用内置的setattr函数更简单:
starting_list = ["Company", "Contact Name", "Email", "Phone", "URL", "Country", "Source"] class NewClass(object): def __init__(self): for item in starting_list: item = str(item).lower().strip().replace(' ', '_') setattr(self, item, 'hi') print(item) obj = NewClass() print(obj.url)
运行上面的代码,你就能正常访问动态添加的属性啦!
内容的提问来源于stack exchange,提问作者Dennis Pitt
相关产品推荐
相关产品推荐

