5

我知道我可以使用这样的字符串获取类的属性:

object.attribute = 'foo'
x = 'attribute'
getattr(object, x)
>>> 'foo'

有没有办法用字符串“深入”到对象的属性?换句话说,如果我的对象包含另一个对象,我怎样才能用字符串获取子对象的属性?例如:

object.object.attribute
4

3 回答 3

12

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!"
于 2012-07-04T03:44:05.380 回答
6

我喜欢这个链接中给出的食谱(实际上评论更好)

从克劳迪乌的回答中借用的例子(这也很棒):

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)
于 2012-07-04T03:39:47.220 回答
4
>>> 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),但我认为.作为字符串的符号看起来更酷......

于 2012-07-04T03:26:22.907 回答