Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pythonic solution to my reduce getattr problem

I used to use reduce and getattr functions for calling attributes in a chain way like "thisattr.thatattr.blaattar" IE:

reduce(getattr, 'xattr.yattr.zattr'.split('.'), myobject)

Works perfectly fine, however now I have a new requirement, my strings can call for a specific number of an attribute as such: "thisattr.thatattr[2].blaattar"

reduce(getattr, 'xattr.yattr[2].zattr'.split('.'), myobject)

Now it doesn't work, I get xattr object has no attribute 'yattr[2]' error.

What would be an elegent solution to this, which works for either way ?

Regards

like image 855
Hellnar Avatar asked Nov 05 '22 10:11

Hellnar


1 Answers

And later you could wish to call some method rather than getting attribute. Re-implementing parts of python approach quickly will become a nightmare. Even current requirement of getattr/getitem support cannot be solved as one-liner.

Instead, you could just use python itself to interpret python,

# Create some object for testing
>>> class A(object):
...     b = None
... 
>>> a = A()
>>> a.b = A()
>>> a.b.b = A()
>>> a.b.b.b = [A(), A(), A(), A()]
>>> a.b.b.b[1].b
>>> a.b.b.b[1].b = "Some result"
>>> 
>>> ctx = {'obj':a, 'val':None}
>>> exec("val = obj.{0}".format('b.b.b[1].b')) in ctx
>>> ctx['val']
'Some result'
like image 102
Daniel Kluev Avatar answered Nov 11 '22 06:11

Daniel Kluev