我知道我可以使用这样的字符串获取类的属性:
object.attribute = 'foo'
x = 'attribute'
getattr(object, x)
>>> 'foo'
有没有办法用字符串“深入”到对象的属性?换句话说,如果我的对象包含另一个对象,我怎样才能用字符串获取子对象的属性?例如:
object.object.attribute
我知道我可以使用这样的字符串获取类的属性:
object.attribute = 'foo'
x = 'attribute'
getattr(object, x)
>>> 'foo'
有没有办法用字符串“深入”到对象的属性?换句话说,如果我的对象包含另一个对象,我怎样才能用字符串获取子对象的属性?例如:
object.object.attribute
该operator.attrgetter
函数执行此操作:
class Foo: pass
f = Foo()
f.bar = Foo()
f.bar.baz = Foo()
f.bar.baz.quux = "Found me!"
import operator
print operator.attrgetter("bar.baz.quux")(f) # prints "Found me!"
我喜欢这个链接中给出的食谱(实际上评论更好)
从克劳迪乌的回答中借用的例子(这也很棒):
class Foo: pass
f = Foo()
f.bar = Foo()
f.bar.baz = Foo()
f.bar.baz.quux = "Found me!"
跟随点的递归 getattr:
>>> rgetattr = lambda o,a: reduce(getattr, a.split('.'), o)
>>> rgetattr(f, 'bar.baz.quux')
'Found me!'
非 lambda 版本是:
def rgetattr(obj, attr):
return reduce(getattr, attr.split('.'), obj)
>>> class Foo: pass
>>> f = Foo()
>>> f.bar = Foo()
>>> f.bar.baz = Foo()
>>> f.bar.baz.quux = "Found me!"
>>> getattr(f, 'bar')
<__main__.Foo instance at 0x01EC5918>
>>> getattr(getattr(f, 'bar'), 'baz')
<__main__.Foo instance at 0x01EC5A30>
>>> getattr(getattr(getattr(f, 'bar'), 'baz'), 'quux')
'Found me!'
编辑:作为一个简单的方法完成:
>>> def dynamic_lookup(obj, dot_attrs):
attr_list = dot_attrs.split(".")
while attr_list:
obj = getattr(obj, attr_list.pop(0))
return obj
>>> f
<__main__.Foo instance at 0x01EC50A8>
>>> dynamic_lookup(f, 'bar.baz.quux')
'Found me!'
很容易适应获取字符串列表(attr_list
直接获取而不是dot_attrs
),但我认为.
作为字符串的符号看起来更酷......