Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 扩展appengine';带缓存的s db.Property_Python_Google App Engine_Descriptor - Fatal编程技术网

Python 扩展appengine';带缓存的s db.Property

Python 扩展appengine';带缓存的s db.Property,python,google-app-engine,descriptor,Python,Google App Engine,Descriptor,我希望为appengine实现一个属性类,非常类似于现有的db.ReferenceProperty。我正在实现自己的版本,因为我需要一些其他默认返回值。我的问题是,如何使属性记住其返回值,以便仅在第一次获取属性时执行数据存储查询?我所拥有的就在下面,它不起作用。我读到属性类不属于实例,而是属于模型定义,因此我猜返回值不是缓存在每个实例中,而是每次都覆盖在模型上。我应该在哪里存储此\u已解析的变量 class PageProperty(db.Property): data_type = Pag

我希望为appengine实现一个属性类,非常类似于现有的
db.ReferenceProperty
。我正在实现自己的版本,因为我需要一些其他默认返回值。我的问题是,如何使属性记住其返回值,以便仅在第一次获取属性时执行数据存储查询?我所拥有的就在下面,它不起作用。我读到属性类不属于实例,而是属于模型定义,因此我猜返回值不是缓存在每个实例中,而是每次都覆盖在模型上。我应该在哪里存储此
\u已解析的
变量

class PageProperty(db.Property):
  data_type = Page

  def get_value_for_datastore(self, model_instance):
    page = super(PageProperty, self).get_value_for_datastore(model_instance)        
    self._resolved = page
    return page.key().name()

  def make_value_from_datastore(self, value):
    if not hasattr(self, '_resolved'):
        self._resolved = Page.get_by_name(value)
    return self._resolved
编辑 亚历克斯的回答当然是有用的。但是,内置的
db.ReferenceProperty
似乎将
\u解析的
变量存储在模型实例上。事实证明:

[...]
    setattr(model_instance, self.__resolved_attr_name(), value)
[...]

def __resolved_attr_name(self):
    return '_RESOLVED' + self._attr_name()
get\u value\u for_datastore
方法被传递给模型实例,但是
make\u value\u from_datastore
不是,那么他们如何从该方法找到
\u RESOLVED
属性呢

编辑2
据我所知,google正在使用
\uuuu get\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这些在自定义类中可用吗?_数据存储
get_value_与其对应项有何不同?

每个模型都存在一个
PageProperty
实例,而不是每个实体(其中一个实体是模型类的实例)。所以我认为您需要一个映射pagename->Page实体的字典,而不是每个PageProperty实例一个属性。例如,可能类似于……:

class PageProperty(db.Property):
  data_type = Page

  def __init__(self, *a, **k):
    super(PageProperty, self).__init__(*a, **k)
    self._mycache = {}       

  def get_value_for_datastore(self, model_instance):
    page = super(PageProperty, self).get_value_for_datastore(model_instance)        
    name = page.key().name()
    self._mycache[name] = page
    return name

  def make_value_from_datastore(self, value):
    if value not in self._mycache:
        self._mycache[value] = Page.get_by_name(value)
    return self._mycache[value]

PageProperty
实例存在于每个模型,而不是每个实体(其中实体是模型类的实例)。所以我认为您需要一个映射pagename->Page实体的字典,而不是每个PageProperty实例一个属性。例如,可能类似于……:

class PageProperty(db.Property):
  data_type = Page

  def __init__(self, *a, **k):
    super(PageProperty, self).__init__(*a, **k)
    self._mycache = {}       

  def get_value_for_datastore(self, model_instance):
    page = super(PageProperty, self).get_value_for_datastore(model_instance)        
    name = page.key().name()
    self._mycache[name] = page
    return name

  def make_value_from_datastore(self, value):
    if value not in self._mycache:
        self._mycache[value] = Page.get_by_name(value)
    return self._mycache[value]

如果您只想更改ReferenceProperty行为的一小部分,您可能只想扩展它,覆盖它的方法。您可能会发现ReferenceProperty很有启发性。

如果您只想更改ReferenceProperty行为的一小部分,您可能只想扩展它,覆盖它的方法。您可能会发现ReferenceProperty很有启发性。

我以为我忽略了从
属性访问实体的方法。
不,属性实例属于整个模型(这就是为什么您将其设置为类主体的一部分!),而不是每个特定实体(模型的实例),这是关键点——因此,只有属性实例才能访问特定实体。您不需要字典——只需将属性值存储在相关实体上即可。这是ReferenceProperty类采用的方法(事实上,还有其他每个属性类)。保持一个dict将导致一个不断增加的大小!我认为我忽略了从
属性访问实体的方法。不,属性实例属于整个模型(这就是为什么将其设置为类主体的一部分!),而不是每个特定实体(模型的实例),这是关键点——因此,只有属性实例才能访问特定实体。您不需要字典——只需将属性值存储在相关实体上即可。这是ReferenceProperty类采用的方法(事实上,还有其他每个属性类)。保持一个dict将导致一个不断增加的大小!我希望它在找不到存储的密钥时返回一个新的实体。还有其他一些事情。关于来源。我不明白
ReferenceProperty
如何在模型实例上存储
\u解析的
实体,而不是像Alex解释的那样,在属性实例的dict中存储。它在传入的模型实例上使用getattr/setattr来设置/检索\ u解析的属性。您应该能够通过子类化ReferenceProperty、重写get并让它捕获db.Error来实现所需的行为。如果引发错误,请创建一个新实例、调用集并返回该实例。我希望它在找不到存储的密钥时返回其类型的新实体。还有其他一些事情。关于来源。我不明白
ReferenceProperty
如何在模型实例上存储
\u解析的
实体,而不是像Alex解释的那样,在属性实例的dict中存储。它在传入的模型实例上使用getattr/setattr来设置/检索\ u解析的属性。您应该能够通过子类化ReferenceProperty、重写get并让它捕获db.Error来实现所需的行为。如果引发错误,请创建新实例、调用集并返回该实例。