getattr nested attributes
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Fri Aug 15 08:21:58 EDT 2008
On Fri, 15 Aug 2008 11:12:04 +0200, Gregor Horvath wrote:
> Peter Otten schrieb:
>
>> make your own function that loops over the attributes, or spell it
>>
>>>>> reduce(getattr, "a.test".split("."), B)
>> 'test'
>>
>>
> Thank's, but this does not work for this case:
>
> class A(object):
> test = "test"
>
> class B(object):
> a = [A(),]
>
> In [70]: reduce(getattr, "a[0].test".split("."), B)
>
> Seems that I have to use eval ?
No you don't.
> I have a mapping text file (data) which contains such attributes strings
> and those attributes should be read.
It might help if you showed what those strings were. I can guess two
likely formats, so here's a few possible solutions.
def grab1(obj, ref):
# Assume ref looks like "attr index"
attr, index = ref.split()
return getattr(obj, attr)[int(index)]
import re
x = re.compile(r'(.*)\[(.*)\]')
def grab2(obj, ref):
# Assume ref looks like "attr[index]"
mo = x.match(ref)
attr = mo.group(1)
index = int(mo.group(2))
return getattr(obj, attr)[index]
def grab3(obj, ref):
# Assume ref looks like "attr[index]"
return eval("obj." + ref)
Here they are in action:
>>> grab1(B(), "a 0")
<__main__.A object at 0xb7c7948c>
>>> grab2(B(), "a[0]")
<__main__.A object at 0xb7c7948c>
>>> grab3(B(), "a[0]")
<__main__.A object at 0xb7c7948c>
Which is fastest?
>>> from timeit import Timer
>>> Timer("grab1(b, 'a 0')",
... "from __main__ import B, grab1; b = B()").repeat()
[3.9213471412658691, 2.8718900680541992, 2.875662088394165]
>>> Timer("grab2(b, 'a[0]')",
... "from __main__ import B, grab2; b = B()").repeat()
[6.1671040058135986, 5.2739279270172119, 5.1346590518951416]
>>> Timer("grab3(b, 'a[0]')",
... "from __main__ import B, grab3; b = B()").repeat()
[33.484487056732178, 34.526612043380737, 34.803802013397217]
The first version is about twice as fast as the regular expression
version, which in turn is about six times as fast as the version using
eval.
--
Steven
More information about the Python-list
mailing list