python class data descriptor list
I ca开发者_如何学Cn'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?
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 and 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)
精彩评论