initializing mutable class attributes

Bengt Richter bokr at oz.net
Wed Sep 1 21:39:30 EDT 2004


On Thu, 02 Sep 2004 00:17:22 GMT, "Dan Perl" <dperl at rogers.com> wrote:

>
>"David Bolen" <db3l at fitlinxx.com> wrote in message
>news:u3c21wnbq.fsf at fitlinxx.com...
>> "Dan Perl" <dperl at rogers.com> writes:
>>
>> > After all this discussion, what do people think about this code?
>>
>> On face value, I'd question why you're going through the extra effort.
>> I may be missing the point in such a small example, but just having an
>> __init__ in the base class that subclasses are supposed to call seems
>> simpler.
>>
>> If you're just trying to find some way to have default attributes that can
>> be used from subclasses without calling __init__, I'd probably just use
>> class level definitions.  For example:
>
>That is exactly what I'm trying to do, and in the initial posting of the
>thread I was mentioning an initialization exactly like yours, but at the
>same time I was pointing out that an initialization like that works only for
>immutable attributes and not for mutable attributes, hence the need for the
>__init__.  Or doing it in __new__ as I showed in the new code.
>
>>           - - - - - - - - - - - - - - - - - - - - - - - - -
>> Python 2.3.4 (#53, May 25 2004, 21:17:02) [MSC v.1200 32 bit (Intel)] on
>win32
>> Type "help", "copyright", "credits" or "license" for more information.
>> >>> class Test(object):
>> ...     attr1 = 666
>> ...
>> >>> class Derived(Test):
>> ...     def __init__(self):
>> ...         self.attr2 = 111
>> ...
>> >>> d = Derived()
>> >>> print d.attr1, d.attr2
>> 666 111
>> >>> print isinstance(d, Test)
>> True
>> >>>
>>           - - - - - - - - - - - - - - - - - - - - - - - - -
>>
>> -- David
>
Here's a way to auto-initialize an instance attribute to a mutable via a class variable
(that happens to be a descriptor ;-)

 >>> class C(object):
 ...     class prop(object):
 ...         def __get__(self, inst, cls=None):
 ...             if inst: return inst.__dict__.setdefault('prop',[])
 ...             return self
 ...         def __set__(self, inst, value): inst.__dict__['prop'] = value
 ...         def __delete__(self, inst): del inst.__dict__['prop']
 ...     prop = prop()
 ...
 >>> c=C()
 >>> vars(c)
 {}
 >>> c.prop
 []
 >>> vars(c)
 {'prop': []}
 >>> c.prop = 'other'
 >>> vars(c)
 {'prop': 'other'}
 >>> C.prop
 <__main__.prop object at 0x00901790>
 >>> del c.prop
 >>> vars(c)
 {}
 >>> c.prop = 'not auto initialized'
 >>> vars(c)
 {'prop': 'not auto initialized'}
 >>> c.prop
 'not auto initialized'
 >>> del c.prop
 >>> c.prop
 []

We can also use it as a base class:

 >>> C.prop
 <__main__.prop object at 0x00901790>
 >>>
 >>> class Derived(C):
 ...     def __init__(self):
 ...         self.attr2 = 111
 ...
 >>> d = Derived()
 >>> print d.prop, d.attr2
 [] 111
 >>> print isinstance(d, C)
 True
 >>> vars(d)
 {'attr2': 111, 'prop': []}
 >>> d.prop
 []

our descriptor is visible via the derived class too, as you would expect
 >>> Derived.prop
 <__main__.prop object at 0x00901790>
 >>> Derived.prop is C.prop
 True

and so ...
 >>> d.prop = 's/b d attribute'
 >>> vars(d)
 {'attr2': 111, 'prop': 's/b d attribute'}
 >>> d.prop
 's/b d attribute'
 >>> del d.prop
 >>> vars(d)
 {'attr2': 111}
 >>> d.prop
 []
 >>> vars(d)
 {'attr2': 111, 'prop': []}

Any use to you? (disclaimer: not tested beyond what you see here ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list