472,371 Members | 1,361 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,371 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 7510
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?
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
2
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
1
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
0
by: jack2019x | last post by:
hello, Is there code or static lib for hook swapchain present? I wanna hook dxgi swapchain present for dx11 and dx9.

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.