我正在尝试使用setattr
和字符串更新类的属性。例如,使用此代码:
class ClassA():
def __init__(self):
self.A = 0
class ClassB():
def __init__(self):
self.CA = ClassA()
CB = ClassB()
setattr(CB, "CA.A", 2)
print(CB.CA.A)
当我执行setattr(CB, "CA.A", 2)
时,它不会更新A
中CA
类的属性CB
。相反,它会创建另一个属性,如图所示:
CB
的班级CA.A
中的然后当我打印print(CB.CA.A)
时,我得到一个0值。
我不明白为什么会这样,如果存在解决方案?
答案 0 :(得分:3)
setattr()
采用文字属性名称。它不支持嵌套属性;名称中的.
只是名称中的一个点,而不是属性分隔符。
换句话说,.
中的CB.CA.A = 2
是语法来访问属性,而不是属性名称的一部分。首先查找CB.CA
,然后将结果分配给结果的A
属性。
您需要拆分.
并使用单独的getattr()
调用来获取父对象:
setattr(getattr(CB, 'CA'), "A", 2)
您可以将该逻辑包装到函数中:
def setattr_nested(base, path, value):
"""Accept a dotted path to a nested attribute to set."""
path, _, target = path.rpartition('.')
for attrname in path.split('.'):
base = getattr(base, attrname)
setattr(base, target, value)