可迭代属性
我有一个库(django-piston),它希望类的一些参数作为类的属性。我想在一个方法中动态地定义这个值。所以我想做类似这样的事情:
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 个回答
1
如果我理解得没错,在django-piston中,一个处理器可以有一些类属性,比如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
2
Sven Marnach给了我一个很好的建议。他告诉我,问题并不是因为属性类不支持迭代,而是因为我在一个类上调用了它。所以我做了以下修改:
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)
现在它可以正常工作了。;-)
14
你原来的代码看起来没问题(不过我不会把局部变量命名成和外部函数一样的名字)。
要注意,属性只在新式类中有效,所以你需要从 object 继承。此外,你需要通过一个实例来调用属性。
如果你需要一个类属性,那么 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