Get attribute this way

K

King

Python's getattr, setattr and __getattribute__ commands works fine
with python types.
For example:
print o.__getattribute__("name")
print getattr(o, "name")
This is the easiest way to get an attribute using a string.

In my case the "Node" class load/creates all the attributes from a xml
file.
Example
<Input name="position" type="float" value="0.5"/>
<Input name="color" type="color" value="0,0,0"/>

There are certain atrributes of compound type.
Example:
# Array of colors, Here we are referring first color and second element
(green)
self.gradient.colors[0][1] = 0.5
# Array of floats, referring first element
self.gradient.positions[0] = 1.0

Color, color array and floats are all custom classes.

Now question is how to get these compound attributes using string as
we do with default singular attributes.
Example:
getattr(o, "gradient.colors[0][1] ")
I need this to save the data of nodes->attributes into a custom xml
format, when loading this data back, I create the node first and then
setup values from the saved xml file.

Prashant
Python 2.6.2
Win XP 32
 
C

Chris Rebert

Python's getattr, setattr and __getattribute__ commands works fine
with python types.
For example:
print o.__getattribute__("name")
print getattr(o, "name")
This is the easiest way to get an attribute using a string.

In my case the "Node" class load/creates all the attributes from a xml
file.
Example
<Input name="position" type="float" value="0.5"/>
<Input name="color" type="color" value="0,0,0"/>

There are certain atrributes of compound type.
Example:
# Array of colors, Here we are referring first color and second element
(green)
self.gradient.colors[0][1] = 0.5
# Array of floats, referring first element
self.gradient.positions[0] = 1.0

Color, color array and floats are all custom classes.

Now question is how to get these compound attributes using string as
we do with default singular attributes.
Example:
getattr(o, "gradient.colors[0][1] ")
I need this to save the data of nodes->attributes into a custom xml
format, when loading this data back, I create the node first and then
setup values from the saved xml file.

Can't you just iterate over the data structure? I'm not seeing why
you'd need to use getattr() and friends in the first place.

for color in self.gradient.colors:
for element in color:
#output XML fragment

#repeat for self.gradient.positions, etc.

Cheers,
Chris
 
K

King

Writing/Reading data to xml is not a problem. The problem is when I
have to write to attributes in xml, where a connections has been
established.
XML:
<Connection sourceattribute="node1.gradient.colors[0][1]"
destattribute="node2.gradient.colors[1][2]"/>

While reading back I have to convert both source and destination
strings into object so that I can call connections function using
source and target attributes.

Prashant
Python 2.6.2
Win XP 32
 
C

Chris Rebert

Writing/Reading data to xml is not a problem. The problem is when I
have to write to attributes in xml, where a connections has been
established.
XML:
<Connection sourceattribute="node1.gradient.colors[0][1]"
destattribute="node2.gradient.colors[1][2]"/>

You did not include an example like this in your original post.

I'd say you're stuck using eval() unless you want to change your
format or write a parser for the subset of Python involved.

Cheers,
Chris
 
K

King

"eval" can solve this problem right away but I am concerned about
security issues. If not "eval" could you suggest something more
efficient way. It won't be a big deal to change the format as
application is still at development stage?

Thanks

Prashant
Python 2.6.2
Win XP 32
 
D

Diez B. Roggisch

King said:
"eval" can solve this problem right away but I am concerned about
security issues. If not "eval" could you suggest something more
efficient way. It won't be a big deal to change the format as
application is still at development stage?

If you don't want to use eval (which is a good thing not to want), you'd
end up (as Chris already told you) writing your own parser for python
subexpressions. Which is laborous.

Or you create a XML-representation of these expressions, which saves you
the parser, but not the evaluator, and bloats the XML. It could look
like this:

<Connection>
<node name="node1">
<attribute name="gradient">
<attribute name="colors">
<item index="0" kind="int">
<item index="1" kind="int"/>
<... # close them all
</node>
<node ... # and the destination

</Connection>

Is this *really* all worth doing, or can't you just overcome your
preconceptions - and use pickle, as it has been suggested to you before?
Potentially with __getstate__/__setstate__ overridden for specific objects.


Diez
 
C

Carl Banks

"eval" can solve this problem right away but I am concerned about
security issues. If not "eval" could you suggest something more
efficient way. It won't be a big deal to change the format as
application is still at development stage?


You are stuck parsing it yourself, then. Apart from eval, there's not
a really handy way to do what you want.

Here's something that might help you get started; it is not by any
means a final solution.

First of all, for simplicity's sake, change the subscript notation to
attribute notation; that is, change "gradient.positions[0]" to
"gradient.positions.0". Then you can find the object you're seeking
like this (untested):


obj = self
while '.' in attr:
next,attr = attr.split('.',1)
try:
index = int(next)
except TypeError:
obj = getattr(obj,next)
else:
obj = obj[index]


Notice what's happening: we're splitting the string at the dot and
using getattr to descend further into the structure. Also, if the
part of the string before the dot is an integer, we index instead.

Hopefully this example will help you understand what doing this
entails and what you have to do to get it work.


Carl Banks
 
B

Bruno Desthuilliers

King a écrit :
Python's getattr, setattr and __getattribute__ commands
s/commands/functions/

works fine
with python types.
For example:
print o.__getattribute__("name")

A very few corner cases set aside - the main one being inside a custom
__getattribute__ method -, you should not directly access
__getattribute__ (nor most __magic_methods__ FWIW).
print getattr(o, "name")
This is the easiest way to get an attribute using a string.

In my case the "Node" class load/creates all the attributes from a xml
file.
Example
<Input name="position" type="float" value="0.5"/>
<Input name="color" type="color" value="0,0,0"/>

There are certain atrributes of compound type.

There's no "compound type" in Python. There are only objects, objects
and objects.
Example:
# Array of colors, Here we are referring first color and second element
(green)
self.gradient.colors[0][1] = 0.5
# Array of floats, referring first element
self.gradient.positions[0] = 1.0

Color, color array and floats are all custom classes.

Now question is how to get these compound attributes using string as
we do with default singular attributes.
Example:
getattr(o, "gradient.colors[0][1] ")

You can't (at least OOTB). the expression:

gradient.colors[0][1]

is a shortcut for:

colors = gradients.__getattribute__("color")
colors_0 = colors.__getitem__(0)
colors_0_1 = colors_0.__getitem__(1)

You can of course do something like

g = getattr(o, "gradient")
c = getattr(g, "colors")
# etc...

but I guess this is not what you're after.
I need this to save the data of nodes->attributes into a custom xml
format, when loading this data back, I create the node first and then
setup values from the saved xml file.

I really don't think you need anything like this to serialize /
unserialize your objects (whatever the format FWIW). You should really
google for +python +serialize +XML, I bet you'd find at least a couple
helpful articles on that topic.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top