7

我有一个库(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?

但我被困在这里。我怎样才能得到一个也可以迭代的属性?

4

3 回答 3

12

您的原始代码看起来不错(尽管我不会将局部变量命名为与封闭函数相同的名称)。

请注意,属性仅适用于新型类,因此您需要从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
于 2011-11-19T23:51:48.810 回答
1

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)

现在可以了。;-)

于 2011-11-20T10:51:51.177 回答
0

如果我理解正确的话,在 django-piston 中,处理程序可以具有 amodelfieldsas 类属性。

如果是这样,您的问题可以这样解决:

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
于 2011-11-20T01:07:31.510 回答