2011-10-06 76 views
3

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

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) 

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

回答

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属性在类上的名称和基础实例的属性。在这种情况下,我通常会预先加下划线。例如:

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

我只是想知道,是否有可能使它只执行一次,因为字段不会改变我不想在每个对象实例上做它。 –

+1

我不确定我是否理解你的意思。这是一个验证类的问题,以便它只包含字段属性?然后,只有在创建课程时才进行一次验证,而不是每次调用“保存”时都进行验证? –

+1

如果是这样的话,那么我会考虑在元类或者类装饰器中包装这种验证。 –