[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Custom class to a dictionary?

oliver@obeattie.com

1/26/2008 11:35:00 AM

Just wondering if it is possible to pass a custom class instance
instance to dict() by way of using methods like you can for iterators
(__iter__, __getitem__ etc.) I see there is no __dict__ -- is there
anything else I can use to achieve this?

Kind Regards,
Oliver
2 Answers

Steven D'Aprano

1/26/2008 12:02:00 PM

0

On Sat, 26 Jan 2008 03:35:18 -0800, Oliver Beattie wrote:

> Just wondering if it is possible to pass a custom class instance
> instance to dict() by way of using methods like you can for iterators
> (__iter__, __getitem__ etc.) I see there is no __dict__ -- is there
> anything else I can use to achieve this?


Just write a method to return (key, value) pairs, and call that:

>>> class Parrot(object):
.... def __init__(self):
.... self.keys = [1, 2, 3, 4]
.... self.values = ["one", "two", "three", "four"]
.... def generate_tuples(self):
.... for k,v in zip(self.keys, self.values):
.... yield (k,v)
....
>>> p = Parrot()
>>> p.generate_tuples()
<generator object at 0xb7d1d78c>
>>> dict(p.generate_tuples())
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}



Here's another way:

>>> class Foo(object):
.... def __getitem__(self, i):
.... if i > 4:
.... raise IndexError
.... return (i, 'foo %d' % i)
....
>>> dict(Foo())
{0: 'foo 0', 1: 'foo 1', 2: 'foo 2', 3: 'foo 3', 4: 'foo 4'}



Bonus marks if you can explain why they both work :)

(Hint: consider the "sequence protocol" and the "iterator protocol".)



--
Steven

oliver@obeattie.com

1/26/2008 1:16:00 PM

0

On Jan 26, 12:01 pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> On Sat, 26 Jan 2008 03:35:18 -0800, Oliver Beattie wrote:
> > Just wondering if it is possible to pass a custom class instance
> > instance to dict() by way of using methods like you can for iterators
> > (__iter__, __getitem__ etc.) I see there is no __dict__ -- is there
> > anything else I can use to achieve this?
>
> Just write a method to return (key, value) pairs, and call that:
>
> >>> class Parrot(object):
>
> ...     def __init__(self):
> ...             self.keys = [1, 2, 3, 4]
> ...             self.values = ["one", "two", "three", "four"]
> ...     def generate_tuples(self):
> ...             for k,v in zip(self.keys, self.values):
> ...                     yield (k,v)
> ...>>> p = Parrot()
> >>> p.generate_tuples()
>
> <generator object at 0xb7d1d78c>>>> dict(p.generate_tuples())
>
> {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>
> Here's another way:
>
> >>> class Foo(object):
>
> ...     def __getitem__(self, i):
> ...             if i > 4:
> ...                     raise IndexError
> ...             return (i, 'foo %d' % i)
> ...>>> dict(Foo())
>
> {0: 'foo 0', 1: 'foo 1', 2: 'foo 2', 3: 'foo 3', 4: 'foo 4'}
>
> Bonus marks if you can explain why they both work :)
>
> (Hint: consider the "sequence protocol" and the "iterator protocol".)
>
> --
> Steven

Sure, I get what you're saying here and thanks for the advice; but I
don't want the keys as the iterator indices -- They should have custom
names (latitude, longitude and elevation). Is this possible (outside
of the custom method to generate two-tuples?) Sorry to be a pain!

The class looks like the below; I just whipped this up real quick but
it can generate the iterators it should -- just the dictionaries
should be different -- {'latitude': 0.0, 'longitude': 0.0,
'elevation': 0.0} or whatever):

class Coordinates(object):
"""Basic object for storing co-ordinate data."""
latitude = 0.0
longitude = 0.0
elevation = 0.0

def __unicode__(self):
return u'Coordinate (%s, %s, %s)' % (self.latitude, self.longitude,
self.elevation)

def __repr__(self):
return '<Coordinates instance at (%s, %s, %s)>' % (self.latitude,
self.longitude, self.elevation)

def __iter__(self):
return iter((self.latitude, self.longitude, self.elevation))

I guess it's just easier to have a dict() method to this end; just
wondered if there was a more 'Pythonic' way to do this.