Итерируемое свойство - PullRequest
       26

Итерируемое свойство

6 голосов
/ 20 ноября 2011

У меня есть библиотека (django-pneon), которая ожидает некоторые параметры класса в качестве свойств класса.Я хотел бы определить это значение динамически в методе.Поэтому я хотел сделать что-то вроде:

class MyHandler(BaseHandler):
    @property
    def fields(self):
        fields = self.model._meta.fields + self.model._meta.virtual_fields
        # Do something more with fields
        return fields

Но это не с:

'property' object is not iterable

Поэтому я хотел сделать что-то вроде:

class iterable_property(property):
    def __iter__(self):
        # What here?

Но язастрял здесь.Как я могу получить свойство, которое также может быть повторено?

Ответы [ 3 ]

10 голосов
/ 20 ноября 2011

Ваш оригинальный код выглядит хорошо (хотя я бы не назвал локальную переменную тем же именем, что и вмещающая функция).

Обратите внимание, что свойства работают только в классах нового стиля, поэтому вам нужно наследовать от object . Также вам необходимо вызвать атрибут свойства из экземпляра.

Если вам нужен атрибут класса, то свойство не будет работать, и вам нужно написать собственный дескриптор для свойства уровня класса:

class ClassProperty(object):
    def __init__(self, func):
        self.func = func
    def __get__(self, inst, cls):
        return self.func(cls)

class A(object):
    model_fields = ['field1', 'field2', 'field3']

    @ClassProperty
    def fields(cls):
        return cls.model_fields + ['extra_field']

print A.fields
1 голос
/ 20 ноября 2011

Свен Марнах указал мне правильное направление. Проблема была не в отсутствии поддержки итерации в классе свойств, а в том, что она была вызвана для класса. Итак, я сделал:

class class_property(property):
    def __get__(self, instance, type):
        if instance is None:
            return super(class_property, self).__get__(type, type)
        return super(class_property, self).__get__(instance, type)

и теперь это работает. ; -)

0 голосов
/ 20 ноября 2011

Если я все правильно понял, в django-pneon обработчик может иметь model и fields в качестве атрибутов класса.

Если это так, ваша проблема может быть решена примерно так:

class MyHandler(BaseHandler):
    model = Post
    class __metaclass__(type):
        @property
        def fields(cls):
            fields = cls.model._meta.fields + cls.model._meta.virtual_fields
            # Do something more with fields
            return fields
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...