Currently I override the class' __setattr__
() towards the end of the class' __init__
() method to prevent new attribute creation -
class Point(object):
def __init__(self):
self.x = 0
self.y = 0
Point.__setattr__ = self._setattr
def _setattr(self, name, value):
if not hasattr(self, name):
raise AttributeError("'" + name + "' not an attribute of Point object.")
else:
super(Point, self).__setattr__(name, value)
Is there a way to avoid manually overriding __setattr__
() and do this automatically with the help of metaclasses?
The closest I came was -
class attr_block_meta(type):
def __new__(meta, cname, bases, dctry):
def _setattr(self, name, value):
if not hasattr(self, name):
raise AttributeError("'" + name + "' not an attribute of " + cname + " object.")
object.__setattr__(self, name, value)
dctry.update({'x': 0, 'y': 0})
cls = type.__new__(meta, cname, bases, dctry)
cls.__setattr__ = _setattr
return cls
class ImPoint(object):
__metaclass__ = attr_block_meta
Is there a more generic way of doing this such that apriori knowledge of the subclass attributes is not required?
Basically, how to avoid the line dctry.update({'x': 0, 'y': 0})
and make this work irrespective of what the names of class attributes are?
P.S. - FWIW I have already evaluated the __slots__
and namedtuple options and found them lacking for my needs. Please don't narrow your focus to the pared down Points() example that I have used to illustrate the question; the actual use case involves a far more complex class.