带模板标签的线程安全性

2024-09-30 08:18:46 发布

您现在位置:Python中文网/ 问答频道 /正文

在阅读了关于线程安全性的this document之后,我感到文档中缺少了一些东西,或者我对它的阅读,或者我的推理。在

举个简单的例子:

class HelloWorldNode(template.Node):
    def render(self, context):
        return "O HAI LOL"

@register.tag(name="hello_world")
def hello_world(parser, tokens):
    """
    Greets the world with wide-eyed awe.
    """
    return HelloWorldNode()

我理解这段代码是为了在使用hello_world标记时构造HelloWorldNode类的新实例。其他示例包括向构造函数传递参数,如下所示:

^{pr2}$

因此,当执行hello_world时,将创建HelloWorldNode的新实例,并且实例字典具有属性message。当然,这个实例必须仅用于标记的给定实例的呈现,因为将其用于其他渲染将意味着绑定到它的数据将不正确。如果不是这样的话,参数会在标记的不同用法之间混淆。在

查看文档中的其他示例,下面是一个来自here的简化示例:

def do_current_time(parser, token):
    tag_name, format_string = token.split_contents()
    return CurrentTimeNode(format_string[1:-1])

由于这将从传递给函数的令牌中获取数据,CurrentTimeNode的唯一工作方式是每次调用do_current_time时实例化一个新的令牌。在

回到文档页面,在那里不和谐开始出现。这很糟糕。在

class CycleNode(Node):
    def __init__(self, cyclevars):
        self.cycle_iter = itertools.cycle(cyclevars)
    def render(self, context):
        return self.cycle_iter.next()

doc说,如果两个页面使用同一个节点,那么使用同一个标记的两个页面可能会遇到竞争条件。我不明白如果两个模板都独立地实例化自己的实例,那么两个模板的呈现怎么会共享同一个实例。

解决这个问题的方法是这样的,文档是这样说的:

class CycleNode(Node):
    def __init__(self, cyclevars):
        self.cyclevars = cyclevars
    def render(self, context):
        if self not in context.render_context:
            context.render_context[self] = itertools.cycle(self.cyclevars)
        cycle_iter = context.render_context[self]
        return cycle_iter.next()

这似乎是用self索引context.render_context。这意味着self用于通过以下两种方式之一标识实例:

  1. self在整个系统中引用该类的一个特定实例
  2. self只引用该类,为了引用实例,需要呈现上下文

如果1为真,为什么不将数据与self关联起来呢?在

如果2为真,并且呈现上下文是“与当前正在呈现的模板的上下文相关联”,那么如何区分同一页上模板标记的两个实例?在

每次调用标记时节点是否单独实例化?如果是,为什么会出现并发问题?如果没有,为什么不呢?在


Tags: 实例文档标记self模板helloworldreturn
1条回答
网友
1楼 · 发布于 2024-09-30 08:18:46

仔细阅读this就知道了。在

模板在加载时被编译。传入tag函数的任何参数都是“static”。它们要么是文本字符串,要么是用作标识符在呈现上下文中查找绑定变量的字符串。在

因此,Node对象被实例化为每个标记,并在使用模板时挂起以备使用(当然,模板可以在任意数量的线程中使用)。在

因此,我的问题中的self是模板中特定节点的标识。结合呈现上下文,这将提供一个唯一的标识,用于挂起实例变量。在

相关问题 更多 >

    热门问题