开发者

python class data descriptor list

开发者 https://www.devze.com 2023-04-11 16:12 出处:网络
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:

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)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号