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 -- http://mail.python.org/mailman/listinfo/python-list