Python3 使用**kwargs设置属性时出现AttributeError
简单来说,我不明白为什么我不能用一个 for
循环和 **kwargs
来设置一个属性,像这样:
class Person():
def __init__(self, onevar, *args, **kwargs):
self.onevar = onevar
for k in kwargs:
self.k = kwargs[k]
print(k, self.k)
def run():
ryan = Person('test', 4, 5, 6, name='ryan', age='fifty')
print(ryan.name)
def main():
run()
if __name__=="__main__":
main()
这段代码返回了以下内容:
AttributeError: 'Person' object has no attribute 'name'
有人知道为什么吗?
3 个回答
0
这一行代码:
self.k = kwargs[k]
... 是在每次循环中设置 self.k
,也就是 self
这个对象里名为 k
的属性,而不是你想象中的 self.value_of_k
。
如果你把这一行改成:
setattr(self, k, kwargs[k])
你应该能得到你想要的结果。
0
编辑: @tzaman 的回答更好。按照他的建议使用 setattr
。
你可能希望 k
变成一个变量,但实际上并不是这样。不过,你可以在 Python 中扩展基本的 object
,并通过内部的 __dict__
属性来设置你的变量。
你还可以使用 iteritems()
来直接获取值。
class Person(object):
def __init__(self, onevar, *args, **kwargs):
self.onevar = onevar
for k,v in kwargs.iteritems():
self.__dict__[k] = v
print(k, self.__dict__.get(k))
5
当你给 self.k
赋值时,其实并不是在创建一个叫做 k 的属性,而是一直在创建一个名为 k
的属性。如果我理解你想做的事情,你需要把
self.k = kwargs[k]
替换成
setattr(self, k, kwargs[k])
这样才能实现你想要的效果。