Appengine NDB交易类方法装饰器订单 [英] Appengine NDB transactional classmethod Decorator Order

查看:88
本文介绍了Appengine NDB交易类方法装饰器订单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要事务性地更新NDB模型的某些属性,并且将更新函数设置为classmethod似乎是明智的:

  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


$

 #将25添加到成本
thing = Thing.add_cost(b $ b

thing.key.id(),25)

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

解决方案

是的,装饰器的顺序很重要。从 PEP 318 - 功能和方法装饰器


申请顺序[16] (从下到上)是它与函数申请的通常顺序相匹配。在数学中,函数的构成转化为 g(f(x))。在Python中, @g @f def foo()转换为 foo = g(f(foo) p>

在您的情况下,它会转化为:

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

一个装饰器在这里,你的 add_cost 函数被 ndb.transactional 包装,函数发生在事务的上下文中,然后由它返回的方法被 classmethod 包装,它返回一个描述符对象

你在一个类中应用多个装饰器,然后装饰器如 classmethod staticmethod 应该是最顶层的。您将收到 TypeError:unbound method .... 的错误类型其他装饰者不接受描述符。



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

< a @ href =https://stackoverflow.com/a/6208458/2549021>为什么@decorator不能装饰静态方法或classmethod?


I need to update some properties of an NDB model transactionally, and it seems sensible to make the update function a classmethod:

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

This is used thus:

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

Does it matter which order the decorators appear?

解决方案

Yes, the order of decorators does matter. From the PEP 318 -- Decorators for Functions and Methods:

The rationale for the order of application [16] (bottom to top) is that it matches the usual order for function-application. In mathematics, composition of functions (g o f)(x) translates to g(f(x)). In Python, @g @f def foo() translates to foo=g(f(foo).

In your case it would translate to:

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

A decorator would wrap the function it is decorating. Here, your add_cost function is wrapped by ndb.transactional so everything thing within the function happens in the context of a transaction and then the method returned by that is wrapped by classmethod which returns a descriptor object.

So, when you apply multiple decorators in a class, then decorators such as classmethod or staticmethod should be the top ones. If you change the order you would receive an TypeError: unbound method .... type of error if the other decorator doesn't accept descriptors.

You can also refer to following post for more details:

Why can @decorator not decorate a staticmethod or a classmethod?

这篇关于Appengine NDB交易类方法装饰器订单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆