Python动态覆盖访问器

时间:2012-11-30 00:31:49

标签: python google-app-engine

我有一个看起来像这样的课程:

class MBObject(ndb.Model):
    id = ndb.StringProperty()
    dictionary = ndb.JsonProperty(indexed=False, default = {})

我想要的是如果某人有MBObject,就像这样:

obj = MBObject()

他们访问任何属性,如:

x = obj.author_id

在幕后它做到了这一点:

x = obj.dictionary["author_id"]

所以基本上我访问的属性,它在字典中查找该属性,而不是访问类的属性。

这也适用于制定者:

x.author_id = 5

应转换为

x.dictionary["author_id"] = 5

这在Python中是否可行,若然,怎么做?

(请不要问为什么,这需要太多解释)

修改 好的,这就是原因:

Google App Engine中的子类很难。创建两个不同的分类对象并运行1个查询以获取不同类类型的对象是不可能的,即使它们从相同的基类继承。您必须使用for循环来查询,或使用他们称为PolyModel的东西,但这会增加写入成本。

所以我想要的是一个动态类,没有预定义的结构。我不想使用GAE Expando类,因为所有属性都默认为索引,这使得写入非常昂贵。 (您可以将默认值设置为无索引,但我想要一些索引和一些未索引,并且它没有提供)

所以我唯一的选择就是将所有属性都放在字典中。为了方便起见,我认为我必须让它看起来像是面向对象的,并隐藏这个属性实际隐藏在字典中的事实。

1 个答案:

答案 0 :(得分:1)

当然,您可以使用Python的魔术方法轻松完成此任务:

__getattr__()

http://www.rafekettler.com/magicmethods.html#access

只需在对象中定义它并为其提供所需的功能:

class MBObject(ndb.Model):

  def __getattr__(self, name):
     if name in self.dictionary:
       return self.dictionary.get(name)
     else:
       raise AttributeError