mixin helper class for unknown attribute access?

Alex Martelli aleax at mail.comcast.net
Mon Oct 31 10:00:49 EST 2005


Steven D'Aprano <steve at REMOVETHIScyber.com.au> wrote:
   ...
> Trying to prevent setting new attributes is a pretty heavy-handed act just
> to prevent a tiny subset of errors. Many people argue strongly that even
> if you could do it, it would be pointless -- or at least, the cost is far
> greater than whatever small benefit there is.

I entirely agree with you (also about the use of __slots__ being a
particularly WRONG way to achieve this).  When I have to suggest a mixin
to avoid accidental setting of misspelled attributes (which does appear
to be a clinically certifiable phobia of programmers coming to Python
from certain other languages) I suggest something like:

class Rats(object):
  def __setattr__(self, name, value):
    if hasattr(self, name):
      super(Rats, self).__setattr__(name, value)
    else:
      raise AttributeError, "can't set attribute %r" % (name,)

The key idea is to exploit hasattr's semantics -- it checks the class as
well as the specific instance.

Example use case:

class Bah(Rats):
  foo = bar = baz = 23

now, given b=Bah(), you can set b.foo, b.bar and b.baz, but no other
attribute of b (of course you can bypass the restriction easily -- such
restrictions are always intended against *accidental* cases, not against
deliberate attacks).

Differently from __slots__, Rats gives no problems with pickling,
inheritance, etc, etc.


Alex



More information about the Python-list mailing list