Will this make sense for your case?
from functools import wraps 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 attibute of " + cname + " object.") object.__setattr__(self, name, value) def override_setattr_after(fn): @wraps(fn) def _wrapper(*args, **kwargs): cls.__setattr__ = object.__setattr__ fn(*args, **kwargs) cls.__setattr__ = _setattr return _wrapper cls = type.__new__(meta, cname, bases, dctry) cls.__init__ = override_setattr_after(cls.__init__) return cls class ImPoint(object): __metaclass__ = attr_block_meta def __init__(self, q, z): self.q = q self.z = z point = ImPoint(1, 2) print point.q, point.z point.w = 3
For more on 'wraps' see.
You may have to play a little with it to make it more elegant, but the general idea is to override __setattr__ only after calling init .
Having said that, the general approach to this is to simply use object.__setattr__(self, field, value) internally to bypass AttributeError:
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 attibute of " + cname + " object.") object.__setattr__(self, name, value) cls = type.__new__(meta, cname, bases, dctry) cls.__setattr__ = _setattr return cls class ImPoint(object): __metaclass__ = attr_block_meta def __init__(self, q, z): object.__setattr__(self, 'q', q) object.__setattr__(self, 'z', z) point = ImPoint(1, 2) print point.q, point.z point.w = 3