Iterable Property

I have a library (django-piston) that expects some class parameters 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 he fails:

 'property' object is not iterable 

So, I wanted to do something like:

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

But I'm stuck here. How can I get a property that can also be repeated?

+6
source share
3 answers

The original code looks good (although I would not name the local variable by the same name as the closing function).

Please note: properties only work in new-style classes, so you need to inherit the object. In addition, you need to call the property attribute from the instance.

If you need a class attribute, the property will not work, and you will need to write your own descriptor for the class 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 
+10
source
Sven Marnach pointed me in the right direction. The problem is not the lack of iteration support in the property class, but in the call to the class. So I did:
 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 now it works .; -)

+1
source

If I understand correctly, in django-piston, a handler can have model and fields attributes as a class.

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 
0
source

Source: https://habr.com/ru/post/901914/


All Articles