python类数据描述符列表

时间:2011-10-06 04:11:41

标签: python descriptor

我似乎无法弄清楚如何获取类数据描述符的列表。基本上,我想对字段和未设置字段运行一些验证。例如:

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]

然后我想在类似的模型中实现它:

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'

如何获取我定义的字段列表?我在想,我可以做到以下几点:

import inspect

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

但我遇到了继承问题,有什么想法吗?

1 个答案:

答案 0 :(得分:2)

为了迭代类的成员,您需要使用inpsect.getmembers。所以你的最后一个例子看起来像这样:

import inspect

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

descriptor中,您应该直接使用python的getattrsetattr内置来替换__dict__

另外,请记住,您要区分类上的descriptor属性名称和基础实例的属性。在这种情况下,我通常会在前面加上下划线。 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)