Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Re: converting dict to object (http://www.velocityreviews.com/forums/t396930-re-converting-dict-to-object.html)

 Gabriel Genellina 12-02-2006 02:08 AM

Re: converting dict to object

At Friday 1/12/2006 22:48, rieh25 wrote:

>If I have a dictionary such as:
>
>d = {'a' : 1, 'b' : 2}
>
>is there a way to convert it into an object o, such as:
>
>o.a = 1
>o.b = 2

>>> class X(object):

.... def __init__(self, d): self.__dict__.update(d)
....
>>> d = {'a' : 1, 'b' : 2}
>>> o=X(d)
>>> o.a

1
>>> o.b

2
>>>

--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ˇgratis!
ˇAbrí tu cuenta ya! - http://correo.yahoo.com.ar

 Michel Claveau 12-02-2006 04:58 AM

Re: converting dict to object

Hi!

Yes.

But...

Try: d = {'a': 1, 'b': 2, 'def': 123}

Ok, I go out...

--
@-salutations

Michel Claveau

 Neil Cerutti 12-02-2006 03:54 PM

Re: converting dict to object

On 2006-12-02, Michel Claveau <mcPas.De.Spam@mclaveauPas.De.Spam.com> wrote:
> Hi!
>
> Yes.
>
> But...
>
> Try: d = {'a': 1, 'b': 2, 'def': 123}
>
> Ok, I go out...

How to convert a list of strings into a list of integers:

a = ['82', '4', '16']

ai = [int(i) for i in a]

Yes.

But...

Try: a = ['82', '4', '16', 'foo']

Ok, I go out...

--
Neil Cerutti

 John Machin 12-02-2006 08:16 PM

Re: converting dict to object

Neil Cerutti wrote:
> On 2006-12-02, Michel Claveau <mcPas.De.Spam@mclaveauPas.De.Spam.com> wrote:
> > Hi!
> >
> > Yes.
> >
> > But...
> >
> > Try: d = {'a': 1, 'b': 2, 'def': 123}
> >
> > Ok, I go out...

>
> How to convert a list of strings into a list of integers:
>
> a = ['82', '4', '16']
>
> ai = [int(i) for i in a]
>
> Yes.
>
> But...
>
> Try: a = ['82', '4', '16', 'foo']
>
> Ok, I go out...

Michel was making (part of) a valid point: dictionaries have more
flexibility in choice of keys than objects have in attribute names.
More completely:

Suppose d.keys() produces ["one", "def", "foo bar", 3, "3"]

o.one is OK.

o.def is not OK ["def" is a keyword] but getattr(o, "def") still works.

o.foo bar is not OK ["foo bar" is not a valid identifier] but
getattr(o, "foo bar") still works.

o.3 is not OK ["3" is not a valid identifier] but getattr(o, "3") still
works.

getattr(o, 3) doesn't work [3 is not a string]; you would have to do
o.__dict__[3] to access the value -- no advantage over keeping it in a
dict.

The OP might consider adding code to the __init__ method to check for
cases where the dictionary key is not a string containing a valid
Python identifier (not a keyword).

Note: I have done a reasonable number of exercises that involved taking
a database table definition or a flat file record definition or the
headings in an XLS worksheet or CSV file and ending up with names for
attributes of Python objects. Various heuristics are necessary of
course to get valid identifers without duplicates, but I've never been
bitten by the keyword problem. I'll have to confess that I wasn't aware
of the problem until the 3rd reading of Michel's message :-)

Any experiences of keyword-bite?

Observation: the keyword module's iskeyword() function gives an easy
check. If one is supporting multiple versions of Python, a more
complicated (overkill?) approach might be desirable: use the latest
version of Python to generate a source file containing the latest
keywords from keyword.kwlist.

Cheers,
John

 Fredrik Lundh 12-02-2006 08:51 PM

Re: converting dict to object

John Machin wrote:

> Any experiences of keyword-bite?

creating or manipulating CSS-styled (X)HTML using an XML binding that
exposes XML attributes as Python attributes.

(this could be viewed as an unnecessary restriction in the Python
parser; it wouldn't be too hard to allow reserved words for keyword
argument names and for attribute access; iirc, Jython already does this,
and Paul Svensson posted a patch for CPython a couple of years ago.
PEP-time, anyone?)

</F>

 Steven D'Aprano 12-03-2006 12:58 AM

Re: converting dict to object

On Sat, 02 Dec 2006 12:16:24 -0800, John Machin wrote:

> The OP might consider adding code to the __init__ method to check for
> cases where the dictionary key is not a string containing a valid
> Python identifier (not a keyword).

If the OP is doing something like this:

attributes = {"length": 15, "id": 2345}
# attribute names are known at compile time, created by the coder
obj.__dict__.update(attributes)
print obj.length
print obj.id

then checking that "length" and "id" are valid identifiers is hardly
necessary, any more than this would be:

class Spam:
def __init__(self, length, id):
check_valid_indentifier("length")
self.length = length
check_valid_indentifier("id")
self.id = id

But if he's doing something like this:

attributes = fetch_user_dict()
# attribute names aren't known until runtime
obj.__dict__.update(attributes)
for key in attributes:
print getattr(obj, key)

then it is also redundant to check for valid identifiers, since getattr()
doesn't need them. However, one might still need to test for accidental
clashes with pre-existing object attributes.

On the third hand, if that's the case then there seems to be no real
advantage to converting the dict into object attributes. Why not just
delegate to a saved copy of the dict?

class Spam:
def __init__(self, d):
self._d = d
def __getitem__(self, key):
return self._d[key]
def __setitem__(self, key, value):
self._d[key] = value

s = Spam({"a": 1, "something else": 2})
s["a"]
s["something else"]

--
Steven.

 John Machin 12-03-2006 01:00 AM

Re: converting dict to object

Steven D'Aprano wrote:
> On Sat, 02 Dec 2006 12:16:24 -0800, John Machin wrote:
>
> > The OP might consider adding code to the __init__ method to check for
> > cases where the dictionary key is not a string containing a valid
> > Python identifier (not a keyword).

>

[snip]
> But if he's doing something like this:
>
> attributes = fetch_user_dict()
> # attribute names aren't known until runtime
> obj.__dict__.update(attributes)
> for key in attributes:
> print getattr(obj, key)
>
> then it is also redundant to check for valid identifiers, since getattr()
> doesn't need them.

but getattr() needs strings.

 Steven D'Aprano 12-03-2006 02:10 AM

Re: converting dict to object

On Sat, 02 Dec 2006 17:00:15 -0800, John Machin wrote:

>
> Steven D'Aprano wrote:
>> On Sat, 02 Dec 2006 12:16:24 -0800, John Machin wrote:
>>
>> > The OP might consider adding code to the __init__ method to check for
>> > cases where the dictionary key is not a string containing a valid
>> > Python identifier (not a keyword).

>>

> [snip]
>> But if he's doing something like this:
>>
>> attributes = fetch_user_dict()
>> # attribute names aren't known until runtime
>> obj.__dict__.update(attributes)
>> for key in attributes:
>> print getattr(obj, key)
>>
>> then it is also redundant to check for valid identifiers, since getattr()
>> doesn't need them.

>
> but getattr() needs strings.

Well, that's true, but if the dict is being read from a file or with
raw_input, the keys will naturally be strings. But even if it is some
arbitrary dict, the keys still don't need to be checked for valid
identifiers, merely checked for strings. And again, keeping the
keys/values in a dict instead of converting to object attributes naturally
solves that problem -- or rather, it isn't a problem that needs to be
solved.

Either way, I see no advantage to taking an arbitrary dict and converting
it into object attributes. It sounds to me like "when the only tool you
have is Java, everything looks like an object attribute" coding :-)

I'd suggest that the "right" answer to the OP's original question "How
do I convert a dict to object attributes?" is "Don't do that", regardless
that it is technically possible.

Maybe I'm wrong and there are lots of really handy uses for such a tactic.
Can anyone suggest any?

--
Steven.

 Neil Cerutti 12-03-2006 02:20 AM

Re: converting dict to object

On 2006-12-02, John Machin <sjmachin@lexicon.net> wrote:
> Neil Cerutti wrote:
>> On 2006-12-02, Michel Claveau <mcPas.De.Spam@mclaveauPas.De.Spam.com> wrote:
>> > Hi!
>> >
>> > Yes.
>> >
>> > But...
>> >
>> > Try: d = {'a': 1, 'b': 2, 'def': 123}
>> >
>> > Ok, I go out...

>>
>> How to convert a list of strings into a list of integers:
>>
>> a = ['82', '4', '16']
>>
>> ai = [int(i) for i in a]
>>
>> Yes.
>>
>> But...
>>
>> Try: a = ['82', '4', '16', 'foo']
>>
>> Ok, I go out...

>
> Michel was making (part of) a valid point: dictionaries have
> more flexibility in choice of keys than objects have in
> attribute names. More completely:
>
> Suppose d.keys() produces ["one", "def", "foo bar", 3, "3"]
>
> o.one is OK.

I made the assumption that Michael was also the original poster,
and had somehow laid a clever trap. If I was wrong about that, my
apologies. It's one thing to ask how to convert 'a' and 'b' to
attributes, but quite another to convert arbitrary text.

> The OP might consider adding code to the __init__ method to
> check for cases where the dictionary key is not a string
> containing a valid Python identifier (not a keyword).

That raises the interesting question of what to do in that case.
Just letting an error occur might be perfectly good behavior.

> Observation: the keyword module's iskeyword() function gives an
> easy check. If one is supporting multiple versions of Python, a
> more complicated (overkill?) approach might be desirable: use
> containing the latest keywords from keyword.kwlist.

Thanks for the pointer to keyword module. I hadn't noticed it
yet.

--
Neil Cerutti

 John Machin 12-03-2006 02:47 AM

Re: converting dict to object

Neil Cerutti wrote:

>
> Thanks for the pointer to keyword module. I hadn't noticed it
> yet.

Bonus: you got an extremely fresh, scarcely used pointer -- I wasn't
aware of it myself till today :-)

Cheers,
John

 All times are GMT. The time now is 03:53 PM.