可归属性

时间:2011-11-19 23:42:27

标签: python class-properties

我有一个库(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 个答案:

答案 0 :(得分:10)

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

注意,属性仅适用于新式类,因此您需要继承 object 。此外,您需要从实例调用属性属性。

如果你需要一个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

答案 1 :(得分:1)

斯文马纳赫指出我正确的方向。这不是缺少对属性类中迭代的支持的问题,而是在类上调用它的问题。所以我做了:

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)

现在可以使用了。 ; - )

答案 2 :(得分:0)

如果我理解正确,在django-piston中,处理程序可以有modelfields作为类属性。

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

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