0

我正在使用 Google App Engine 多模型对可以具有多个属性实例的数据进行建模——例如,一个联系人可以有多个电话号码。说这是我的设置:

class Foo(polymodel.PolyModel):
    some_prop = ndb.StringProperty()

    @property
    def bar(self):
        return Bar.query(Bar.foo == self.key)

class Bar(ndb.Model):
    foo = ndb.KeyProperty(kind = Foo)
    other_prop= ndb.StringProperty()

(在阅读了这篇关于数据建模的 GAE 文章后,我得到了这种方法:https ://developers.google.com/appengine/articles/modeling )

现在当我这样做时:

Foo._properties

我只能访问以下内容:

{'some_prop': StringProperty('some_prop'), 
 'class': _ClassKeyProperty('class', repeated=True)}

有什么方法可以访问所有属性,包括那些用“@property”定义的?

非常感谢您对我哪里出错的任何帮助或见解。- 李

更新:基于@FastTurle 的出色回答,我现在添加了一个类方法,它返回类属性以及通过@property 标记为属性的方法:

def props(self):
    return dict(self._properties.items() +  \
                   {attr_name:getattr(self,attr_name) for \
                    attr_name, attr_value in \
                    Foo.__dict__.iteritems() if \
                    isinstance(attr_value,property)}.items())
4

1 回答 1

2

执行Foo._properties应该让您访问您定义的任何属性polymodel.PolyModel,继承自google.appengine.ext.db.Property.

这意味着KeyProperty,StringProperty等... 将出现在 中Foo._properties,所以我假设您现在需要找到所有由property.

幸运的是,这并不难。首先,快速进入装饰器(如果您已经知道,请原谅我)。

在 python中,装饰器只是语法糖。例如,这两种方法的结果是一样的:

@property
def bar(self):
    pass

def bar(self):
    pass
bar = property(bar)

对我们来说幸运的是,property(obj)返回一个新property对象。这也意味着它也@property返回一个property对象。您可以将其property视为一个班级!最后可以isinstance(bar, property)用来查看是否bar是一个属性。

最后,我们可以通过检查每个Foo的属性并仅选择那些是property实例的属性来使用它。

for attr_name, attr_value in Foo.__dict__.iteritems():
    if isinstance(attr_value, property):
        print attr_name, attr_value

# bar, <property object at ...>
于 2013-08-16T18:27:19.860 回答