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