Michele Simionato wrote:
This article could give you same idea (it is doing the opposite,
warning you
if an attribute is overridden):
http://stacktrace.it/articoli/2008/06/i-pericoli-della-programmazione-con-i-mixin1/
There is also a recipe that does exactly what you want by means of a
metaclass:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252158
It is so short I can write it down here:
# requires Python 2.2+
def frozen(set):
"Raise an error when trying to set an undeclared name."
def set_attr(self,name,value):
if hasattr(self,name):
set(self,name,value)
else:
raise AttributeError("You cannot add attributes to %s" %
self)
return set_attr
class Frozen(object):
"""Subclasses of Frozen are frozen, i.e. it is impossibile to add
new attributes to them and their instances."""
__setattr__=frozen(object.__setattr__)
class __metaclass__(type):
__setattr__=frozen(type.__setattr__)
I don't get it. Why use a metaclass? Wouldn't the following be the same,
but easier to grasp:
class Frozen(object):
def __setattr__(self, name, value):
if not hasattr(self, name):
raise AttributeError, "cannot add attributes to %s" % self
object.__setattr__(self, name, value)
Btw, the main drawback with Frozen is that it will not allow to set any
new attributes even inside __init__.
Some people would advise to use __slots__:
http://docs.python.org/ref/slots.html#l2h-222
Some other people would advise NOT to use __slots__:
http://groups.google.com/group/comp.lang.python/msg/0f2e859b9c002b28
Personally, if I must absolutely, I'd go for explicitely freeze the
object at the end of __init__:
class Freezeable(object):
def freeze(self):
self._frozen = None
def __setattr__(self, name, value):
if hasattr(self, '_frozen') and not hasattr(self, name):
raise AttributeError
object.__setattr__(self, name, value)
class Foo(Freezeable):
def __init__(self):
self.bar = 42
self.freeze() # ok, we set all variables, no more from here
x = Foo()
print x.bar
x.bar = -42
print x.bar
x.baz = "OMG! A typo!"
Cheers,
RB
--
http://mail.python.org/mailman/listinfo/python-list