"literal" objects

Bjorn Pettersen bjorn.pettersen at comcast.net
Thu Dec 25 04:48:42 EST 2003


bokr at oz.net (Bengt Richter) wrote in news:bsd3ra$m85$0 at 216.39.172.122:

> On Wed, 24 Dec 2003 09:23:23 -0800, Donn Cave <donn at u.washington.edu>
> wrote: 
> 
>>In article <%QbGb.2109$1f6.732 at newssvr25.news.prodigy.com>,
>> "Moosebumps" <purely at unadulterated.nonsense> wrote:
> [...]
>>
>>> A thought that occured to me is that classes are implemented as
>>> dictionaries (correct?).  So you could have a dictionary like this:
>>> 
>>> x = {'a': 3, 'b': 5}
>>> y = {'a': 5, 'b': 15}
>>> 
>>> This would be the __dict__ attribute of an object I suppose.  But I
>>> don't see anyway to assign it to a variable so you could access them
>>> like x.a and y.a.  I don't know if this would be a "nice" way to do
>>> it or not. 

It wouldn't -- using a proper __init__ initializer when you know the
structure of the object is by far the better approach. If you didn't
care about accessing the contained items using dot notation, you could
simply do: 

   x = dict(a=3, b=5)
   y = dict(a=5, b=15)

If you need dot notation, there are several ways of doing it. Continuing
with a dict subclass you can e.g. do: 

   >>> class Dict(dict):
   ...     def __setattr__(self, attr, val):
   ...         self[attr] = val
   ...     def __getattr__(self, attr):
   ...         return self[attr]
   ...
   >>> x = Dict(a=3, b=5)
   >>> x.a
   3
   >>> x.b
   5
   >>> x.c = 42
   >>> x.c
   42
   >>> x
   {'a': 3, 'c': 42, 'b': 5}
   >>>


>>class A:
>>    def __init__(self):
>>        self.__dict__.update({'a': 3, 'b': 5})
>>x = A()
>>print x.a, x.b
>>
>>Would it be nice?  No, it would be horrible, unless you had some
>>very compelling reason to do this, in which case it would be fine.
> This form of the above can be useful, though:
> 
>  class A:
>      def __init__(self, **kw):
>          self.__dict__.update(kw)
>  x = A(a=3, b=5)
>  print x.a, x.b
[...]

This is the "inverse" of my example above. Which one I'd choose depends
on how much I know about the objects and if there are many other mehtods
I need to add. E.g. the __setattr__ in Dict above makes it more typing
intensive to add methods to the class. 

If your use case for this simple struct is to have a very large number
of such objects, this might be a legitimate use of __slots__, i.e. the
following class will take less memory than a dictionary solution (but
not enough less that it makes any sense unless you have _many_ instances
of it): 

   >>> class Data(object):
   ...     __slots__ = 'a b'.split()
   ...     def __init__(self, a, b):
   ...         self.a, self.b = a, b
   ...     def __repr__(self):
   ...         return '<Data a=%s b=%s>' % (self.a, self.b)
   ...     __str__ = __repr__
   ...
   >>> x = Data(a=3, b=5)
   >>> y = Data(b=15, a=3)
   >>> x
   <Data a=3 b=5>
   >>> y
   <Data a=3 b=15>
   >>>

it also has the side-effect that you can't assign to new attributes:

   >>> x.c = 42
   Traceback (most recent call last):
     File "<stdin>", line 1, in ?
   AttributeError: 'Data' object has no attribute 'c'
   >>>

which is the price we pay for this memory optimization :-)


> Regards,
> Bengt Richter


-- bjorn




More information about the Python-list mailing list