473,320 Members | 2,158 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

getattr nested attributes

Hi,

class A(object):
test = "test"

class B(object):
a = A()
In [36]: B.a.test
Out[36]: 'test'

In [37]: getattr(B, "a.test")
---------------------------------------------------------------------------
<type 'exceptions.AttributeError' Traceback (most recent call last)

/<ipython consolein <module>()

<type 'exceptions.AttributeError'>: type object 'B' has no attribute
'a.test'

???

Documentation says B.a.test and getattr(B, "a.test") should be equivalent.

http://docs.python.org/lib/built-in-funcs.html

any help?

Greg
Aug 15 '08 #1
8 7887
Gregor Horvath wrote:
any help?
I guess you missunderstood the sentence "For example, getattr(x,
'foobar') is equivalent to x.foobar.". getattr(x, "foo.bar") is not
equivalant to x.foo.bar.
Aug 15 '08 #2
Gregor Horvath wrote:
Hi,

class A(object):
test = "test"

class B(object):
a = A()
In [36]: B.a.test
Out[36]: 'test'

In [37]: getattr(B, "a.test")
---------------------------------------------------------------------------
<type 'exceptions.AttributeError' Traceback (most recent call
last)

/<ipython consolein <module>()

<type 'exceptions.AttributeError'>: type object 'B' has no attribute
'a.test'

???
I think that message is pretty clear. B doesn't have an attribute "a.test",
it has an attribute "a" which in turn has an attribute "test". You can
access it by calling getattr() twice,
>>getattr(getattr(B, "a"), "test")
'test'

make your own function that loops over the attributes, or spell it
>>reduce(getattr, "a.test".split("."), B)
'test'
Documentation says B.a.test and getattr(B, "a.test") should be equivalent.

http://docs.python.org/lib/built-in-funcs.html
No, it doesn't.

Peter
Aug 15 '08 #3
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)
---------------------------------------------------------------------------
<type 'exceptions.AttributeError' Traceback (most recent call last)

/<ipython consolein <module>()

<type 'exceptions.AttributeError'>: type object 'B' has no attribute 'a[0]'

Seems that I have to use eval ?
I have a mapping text file (data) which contains such attributes strings
and those attributes should be read.

--
Greg
Aug 15 '08 #4
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)
---------------------------------------------------------------------------
<type 'exceptions.AttributeError' Traceback (most recent call
last)

/<ipython consolein <module>()

<type 'exceptions.AttributeError'>: type object 'B' has no attribute
'a[0]'
Like the screwdriver doesn't work with a nail?
Seems that I have to use eval ?
I have a mapping text file (data) which contains such attributes strings
and those attributes should be read.
When you pass data to eval() it becomes code. If you trust the source of
that text file that would be the easiest approach. Otherwise google
for 'safe eval'.

Peter
Aug 15 '08 #5
On Fri, 15 Aug 2008 11:12:04 +0200, Gregor Horvath wrote:
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)
---------------------------------------------------------------------------
<type 'exceptions.AttributeError' Traceback (most recent call last)

/<ipython consolein <module>()

<type 'exceptions.AttributeError'>: type object 'B' has no attribute 'a[0]'

Seems that I have to use eval ?
Nope. Always ask getattr for small things and it will like you:
>>getattr(getattr(B, 'a')[0], 'test')
'test'
>>>
it works because:
>>getattr(B, 'a') == B.a
True
>>getattr(B, 'a')[0] == B.a[0]
True
>>>
--
Regards,
Wojtek Walczak,
http://www.stud.umk.pl/~wojtekwa/
Aug 15 '08 #6
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
Aug 15 '08 #7
On 15 Aug, 10:35, Gregor Horvath <g...@gregor-horvath.comwrote:
>
<type 'exceptions.AttributeError'>: type object 'B' has no attribute
'a.test'
You have to realise that attributes can have names beyond those
supported by the usual attribute access syntax. For example:

class C: pass

setattr(C, "x.y", 123)
getattr(C, "x.y") # gives 123
setattr(C, "class $$$", 456)
getattr(C, "class $$$") # gives 456

Note that there's no way of using the object.name syntax to access
these attributes, although some proposals have been made to allow it
in some fashion. What you should conclude from this is that the name
argument to setattr and getattr is just a name, not an expression,
even if you can construct names which look like expressions or other
syntactically meaningful fragments of code.
Documentation says B.a.test and getattr(B, "a.test") should be equivalent.

http://docs.python.org/lib/built-in-funcs.html
No, the documentation says that the name must be "the name of one of
the object's attributes", not an expression fragment that if combined
with the name of the object and evaluated would yield an attribute
from some object or other reachable via the original object.

Paul
Aug 15 '08 #8
Gregor Horvath wrote:
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)
---------------------------------------------------------------------------
<type 'exceptions.AttributeError' Traceback (most recent call last)
getattr fetches a named attribute, it doesn't evaluate random code
snippets. please read the manual.

</F>

Aug 15 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Johnny | last post by:
Hi, I wonder what is the difference between the built-in function getattr() and the normal call of a function of a class. Here is the details: getattr( object, name) Return the value of...
8
by: Steven D'Aprano | last post by:
I came across this unexpected behaviour of getattr for new style classes. Example: >>> class Parrot(object): .... thing = .... >>> getattr(Parrot, "thing") is Parrot.thing True >>>...
13
by: Pierre | last post by:
Hi, Sorry in advance, english is not my main language :/ I'd like to customize the result obtained by getattr on an object : if the object has the requested property then return it BUT if the...
4
by: Emin | last post by:
Dear experts, I got some unexpected behavior in getattr and copy.deepcopy (see transcript below). I'm not sure if this is actually a bug in copy.deepcopy or if I'm doing something too magical...
2
by: Sledge | last post by:
Hi. I am trying to dynamically load a class and attributes at run time. I do not know what classes will be referenced until run time. I have it loading the module correctly, but when I use...
3
by: Rotlaus | last post by:
Hello, lets assume i have some classes: class A(object): def __init__(self): b = B() class B(object): def __init__(self):
9
by: Gabriel Rossetti | last post by:
Hello, I can't get getattr() to return nested functions, I tried this : .... def titi(): .... pass .... f = getattr(toto, "titi") .... print str(f) .... Traceback...
0
by: Gabriel Genellina | last post by:
En Wed, 20 Aug 2008 05:34:38 -0300, Gabriel Rossetti <gabriel.rossetti@arimaz.comescribi�: Yes, functions are objects, but inner functions aren't attributes of the outer; they live in its...
4
by: maestro | last post by:
Why are these functions there? Is it somehow more idiomatic to use than to do obj.field ? Is there something you can with them that you can't by obj.field reference?
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.