On Mon, Jul 25, 2011 at 8:36 AM, Steven W. Orr <ste...@syslang.net> wrote:
> I have been doing a lot of reading. I'm starting to get it. I think it's > really cool as well as dangerous, but I plan on being respectful of the > construct. I found a web page that I found quite readable. > > http://cleverdevil.org/**computing/78/<http://cleverdevil.org/computing/78/> > > So, I tried to run the example code (below), and I get AttributeError. If > someone can get me over this hump, I'd be grateful. It complains that Person > has no _fields attribute, but the print hello I have in EnforcerMeta doesn't > happen either. Am I doing something wrong? > > I'm running python 2.6.2 > > Here's the error: > > 585 > ./meta1.py > Traceback (most recent call last): > File "./meta1.py", line 38, in <module> > swo.name = 'swo' > File "./meta1.py", line 27, in __setattr__ > if key in self._fields: > AttributeError: 'Person' object has no attribute '_fields' > > > And here's the code: > > #! /usr/bin/python > # http://cleverdevil.org/**computing/78/<http://cleverdevil.org/computing/78/> > class Field(object): > def __init__(self, ftype): > self.ftype = ftype > > def is_valid(self, value): > return isinstance(value, self.ftype) > > class EnforcerMeta(type): > def __init(cls, name, bases, ns): > # Store the field definitions on the class as a dictionary > # mapping the field name to the Field instance. > print 'Hello' > cls._fields = {} > > # loop through the namespace looking for Field instances. > for key, value in ns.items(): > if isinstance(value, Field): > cls._fields[key] = value > > class Enforcer(object): > # attach the metaclass > __metaclass__ = EnforcerMeta > > def __setattr__(self, key, value): > if key in self._fields: > if not self._fields[key].is_valid(**value): > raise TypeError('Invalid type for field.') > super(Enforcer, self).__setattr__(key, value) If I understand what you are trying to do here (other than playing with metaclasses), you should be able to implement this as a descriptor ( http://docs.python.org/reference/datamodel.html#implementing-descriptors). Something like (untested): class Field(object): def __init__(self, name, type): self.ftype = type self.name = name def __get__(self, instance, owner): return getattr(instance, self.name) def __set__(self, instance, value): if not self.is_valid(value): raise TypeError() setattr(instance, self.name, value) def is_valid(self, value): return isinstance(value, self.ftype) > > class Person(Enforcer): > name = Field(str) > age = Field(int) > > if __name__ == '__main__': > swo = Person() > swo.name = 'swo' > print 'swo:', swo > >
-- http://mail.python.org/mailman/listinfo/python-list