python class data descriptor list
Question: I can't seem to figure out how to get a list of a classes data descriptors.
Basically, I want to run some validation against the fields and unset fields.
For instance:

    
    
    class Field (object):
        def __init__ (self, name, required=False):
            self.name = name
            self.required = required
    
        def __set__ (self, obj, val):
            obj.__dict__[self.name] = val
    
        def __get__ (self, obj):
            if obj == None:
                raise AttributeError
            if self.name not in obj.__dict__:
                raise AttributeError
            return obj.__dict__[self.name]
    

Then I wanted to implement it in a model like so:

    
    
    class BaseModel (object):
        some_attr = Field('some_attr', required=True)
        def save (self):
            for field in fields:
                if field.required and field.name not in self.__dict__:
                    raise Exeception, 'Validation Error'
    

How would I go about getting a list of the fields I define? I was thinking, I
could do the following:

    
    
    import inspect
    
    fields = []
    for attr in self.__class__.__dict__:
        if inspect.isdatadescriptor(self.__class__.__dict__[attr]):
            fields.append(attr)
    

But I ran into problems with inheritance, any ideas?


Answer: In order to iterate over the classes' members you need to use
`inpsect.getmembers`. So your last example would look like this:

    
    
    import inspect
    
    fields = []
    for member_name, member_object in inspect.getmembers(self.__class__):
        if inspect.isdatadescriptor(member_object):
             fields.append(member_name)
    

In your `descriptor` you should replace accessing `__dict__` directly with
python's [getattr](http://docs.python.org/library/functions.html#getattr) and
[setattr](http://docs.python.org/library/functions.html#setattr) builtins.

Also, keep in mind that you want to make a distinction between the
`descriptor` attribute's name on the class and the underlying instance's
attribute. In cases like this I usually prepend and underscore. e.g.:

    
    
    class Field (object):
        def __init__(self, name, required=False):
            self.name = '_' + name
            self.required = required 
    
        def __set__(self, obj, val):
            setattr(obj, self.name, val)
    
        def __get__(self, obj):
            return getattr(obj, self.name)
    

