Question
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?
Solution
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
OTHER TIPS
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