質問

I have a library (django-piston) which is expecting some parameters of the class as class properties. I would like to define this value dynamically in a method. So I wanted to do something like:

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

But it fails with:

'property' object is not iterable

So I wanted to do something like:

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

But I got stuck here. How could I get a property which can also be iterated over?

役に立ちましたか?

解決

Your original code looks fine (though I wouldn't have named the local variable the same name as the enclosing function).

Note, properties only work in new-style classes, so you will need to inherit from object. Also, you need to call the property attribute from an instance.

If you need a class attribute, then property won't work and you'll need to write your own descriptor for a class-level property:

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

他のヒント

Sven Marnach pointed me into the right direction. It was not the problem of missing support for iteration in property class, but that it was called on a class. So I made:

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)

and it works now. ;-)

If I've understood things correctly, in django-piston a handler can have a model and fields as class attributes.

If so, your problem could be solved something like this:

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top