initializing mutable class attributes
Dan Perl
dperl at rogers.com
Thu Sep 2 00:48:55 EDT 2004
Someone else (Shalabh) suggested descriptors for the same problem but I
didn't get to consider such a solution until now. Your posting gave me a
chance to do that. Thanks. I do think though that it is way too much for
just initializing the attributes without an __init__, especially because I
think now I can do it by overriding __new__.
Dan
"Bengt Richter" <bokr at oz.net> wrote in message
news:ch5tki$csm$0$216.39.172.122 at theriver.com...
> 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