Appengine NDB事务类classmethod Decorator Order

时间:2016-05-09 05:59:54

标签: python google-app-engine

我需要以事务方式更新NDB模型的某些属性,并且使更新函数成为类方法似乎是明智的:

class Thing(ndb.Model):
    cost=ndb.IntegerProperty()
    @classmethod
    @ndb.transactional()
    def add_cost(cls, thid, amount):
        thing=cls.get_by_id(thid)
        thing.cost+=amount
        return thing

因此使用:

# Add 25 to cost
thing=Thing.add_cost(thing.key.id(), 25)

装饰器出现的顺序是否重要?

1 个答案:

答案 0 :(得分:5)

是的,装饰者的顺序很重要。来自PEP 318 -- Decorators for Functions and Methods

  

order of application [16](从下到上)的基本原理是它与函数应用程序的通常顺序相匹配。在数学中,函数(g o f)(x)的组合转换为g(f(x))。在Python中,@g @f def foo()会转换为foo=g(f(foo)

在您的情况下,它将转换为:

classmethod(ndb.transactional(Thing.add_cost(...)))

装饰器将包装它正在装饰的函数。这里,add_cost函数由ndb.transactional包装,因此函数中的所有内容都发生在事务的上下文中,然后由它返回的方法由classmethod包装,返回classmethod 3}}

因此,当您在类中应用多个装饰器时,staticmethodTypeError: unbound method ....等装饰器应该是最顶层的装饰器。如果您更改顺序,如果其他装饰者不接受描述符,您将收到mAdapter = new SearchAdapter(rootView.getContext(), (Category)subCategoryList); 类型的错误。

您还可以参考以下帖子了解更多详情:

descriptor object