список дескрипторов данных класса Python - PullRequest
3 голосов
/ 06 октября 2011

Я не могу понять, как получить список дескрипторов данных классов.По сути, я хочу выполнить некоторую проверку для полей и неустановленных полей.Например:

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 Ответ

2 голосов
/ 06 октября 2011

Чтобы перебрать членов классов, вы должны использовать 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 вы должны заменить доступ к __dict__ напрямую на встроенные getattr и setattr Python.

Также имейте в виду, что вы хотите провести различие между именем атрибута 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...