gpt4 book ai didi

python - 由于装饰器实现而导致的数据库模型串扰

转载 作者:太空宇宙 更新时间:2023-11-03 14:37:20 25 4
gpt4 key购买 nike

我有一个在 App Engine 上运行的 Web 服务器,它使用 ndb 进行数据存储。

数据模型看起来像这样:

@acl
class MyModel(ndb.Model):
...
access_control = ndb.JsonProperty(default={})

我使用 @acl 装饰器通过一些访问控制方法来增强我的模型。装饰器看起来像这样:

def acl(model):
def grant(self, subject, credentials):
logging.debug("ACL before: {}".format(self.access_control))
self.access_control[subject] = { ... } # Set correct value.
logging.debug("ACL after: {}".format(self.access_control))
model.grant = grant
...
...

从我的应用程序中,我希望这样调用它:

>>> mdl = MyModel(...)
>>> mdl.grant("someone", "creds")
ACL before: {}
ACL after: { < properly populated access_control > }

但是我得到了类似的东西:

>>> mdl1 = MyModel(...)
>>> mdl1.grant("someone", "creds")
ACL before: {}
ACL after: { < properly populated access_control > }

>>> mdl2 = MyModel(...)
>>> mdl2.grant("someone else", "other creds")
ACL before: { < values from mdl1 > }
ACL after: { < values from mdl1 concatenated with mdl2 > }

这个错误让我怀疑 grant() 函数中的 self 不知何故表现得像一个全局值,因为它正在积累以前调用的数据,即使这些调用是在不同的实例上执行的。

问题是:为什么我的模型会在它们之间溢出数据?装饰器上下文中的 self 与类方法上下文中的 self 相同吗?

最佳答案

模型属性是静态元素。另请参阅correct way to define class variables in Python .

类装饰器的存在可能会干扰 ndb 内部的正常操作,而 ndb 内部通常会负责属性值的正确初始化。

我对类装饰器不够熟悉,所以我不确定是否/如何使用修改后的装饰器来解决这个问题。也许是这样的(显式初始化属性)?

def acl(model):
def grant(self, subject, credentials):
self.access_control = {} # Always start with the default value
logging.debug("ACL before: {}".format(self.access_control))
self.access_control[subject] = { ... } # Set correct value.
logging.debug("ACL after: {}".format(self.access_control))
model.grant = grant

我选择实现类似功能的(恕我直言更容易理解)解决方案是使用普通类继承而不是装饰器(但请注意相同的值重置):

class ACLModel(ndb.Model):
access_control = ndb.JsonProperty(default={})

def grant(self, subject, credentials):
self.access_control = {}
self.access_control[subject] = { ... } # Set correct value.

class MyModel(ACLModel):
...
# other specific properties

继承方法使我可以轻松地对多个模型使用相同的访问控制代码(自包含)。装饰器方法会对可以使用它的模型提出额外的要求 - 它们都需要有一个access_control属性 - 不是独立的。

关于python - 由于装饰器实现而导致的数据库模型串扰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46837021/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com