A Suggestion (please read and respond)
D-Man
dsh8290 at rit.edu
Mon Oct 30 18:12:55 EST 2000
I seem to be missing something here:
namely the message that this is a reply to.
Anyone know why I'm getting some, but not all messages?
-D
On Mon, 30 Oct 2000 15:35:31 Alex Martelli wrote:
> "Courageous" <jkraska1 at san.rr.com> wrote in message
> news:39FDAE7D.2259B2EC at san.rr.com...
> [snip]
> > strict class Joe:
> > i = 3
> > j = Joe()
> > j.j = 1
> >
> > >>>> Attribute error: strict classes only support instance attributes
> > which also exist as class attributes. Valid instance attributes are:
> > 'i' (which is an integer in its class context)
> >
> > You could do something similar with every possible namespace, although
> > I haven't thought out what the syntax might be for modules...
> >
> > Note for classes you can, by overriding the set attr method, implement
> > this now.
>
> Very, very true. Moreover, you can do it by mix-in inheritance
> if you don't need to have your own special meaning for
> __setattr__ (if you do, you will need explicit delegation).
>
> For example, this gets close:
>
> -- cut: strict.py
> class Strict:
> def __setattr__(self, name, value):
> if hasattr(self.__class__,name):
> self.__dict__[name]=value
> else:
> names = [x for x in self.__class__.__dict__.keys()
> if not x.startswith('__')]
> names.sort()
> message = ("Class %s is strict: only attributes %s can be set" %
> (self.__class__.__name__, names))
> raise AttributeError,message
> -- end of cut
>
> >>> import strict
> >>> class Mine(strict.Strict):
> a=1; b=2; c="foo"; d=()
>
> >>> x=Mine()
> >>> x.a=23
> >>> x.z='foo'
> Traceback (innermost last):
> File "<pyshell#20>", line 1, in ?
> x.z='foo'
> File "D:\Python20\strict.py", line 11, in __setattr__
> raise AttributeError,message
> AttributeError: Class Mine is strict: only attributes ['a', 'b', 'c', 'd']
> can be set
>
> However, the message is misleading for _inherited_ attributes (a bit too
> strict, let's say...):
>
> >>> class Yours(Mine):
> z=45; y='wep'
>
>
> >>> y=Yours()
> >>> y.z='plop'
> >>> y.a=23
> >>> y.n=42
> Traceback (innermost last):
> File "<pyshell#48>", line 1, in ?
> y.n=42
> File "D:\Python20\strict.py", line 11, in __setattr__
> raise AttributeError,message
> AttributeError: Class Yours is strict: only attributes ['y', 'z'] can be set
> >>>
>
> It's not true -- attribute a can be set as well, as we have just
> demonstrated! -- but it ain't too hard to fix... left as an
> exercise to the reader!-) [these metaprogramming tricks
> are fascinating, though I think their status is close to what
> Zen thinks of metaphysical reflections -- just a mind-
> obstacle in the quest for true simplicity...:-)]
>
>
> Alex
>
> Thinking up strategies for that to be arranged gets
> interesting -- looking up a name in the graph of
> base classes each time, recursively, is not too hard
> of course:
>
> def isnameok_inclass(klass, name):
> if klass.__dict__.has_key(name):
> return klass
> for super in klass.__bases__:
> isokthere=isnameok_inclass(super,name)
> if isokthere: return isokthere
> return None
>
> def isnameok(object, name):
> return isnameok_inclass(object.__class__, name)
>
> and change the line in class Strict
> if self.__class__.__dict__.has_key(name):
> into
> if isnameok(self, name):
>
> but optimizing that is more interesting. For
> example, if we can assume that a class's bases
> are not changed during runtime (or if special
> re-processing can be required if they do), we
> could compute an '_allbases' field in a class
> the first time is needed:
>
> def allbasesof(klass):
> if not klass.__dict__.has_key('_allbases'):
> all = list(klass.__bases__)
> for super in klass.__bases__:
> all.extend(allbasesof(super))
> klass._allbases = all
> return klass._allbases
>
>
>
>
> --
> http://www.python.org/mailman/listinfo/python-list
>
More information about the Python-list
mailing list