gpt4 book ai didi

django - `SyntaxError: no binding for nonlocal ' topics_with_log_tag ' found` 虽然它是有界的

转载 作者:行者123 更新时间:2023-12-01 15:24:11 25 4
gpt4 key购买 nike

我想获取带有指定“日志”标签的主题:

在嵌套函数内 get_topics_with_log_tag ,我设置变量topics_with_log_tag非本地:

def log(request):
"""Show all topics and entries with log tags"""

topics = Topic.objects.all()
#select entries with log tag
def get_topics_with_log_tag(topics):
nonlocal topics_with_log_tag
topics_with_log_tag = []
for topic in topics:
for entry in topic.entry_set.all():
if "#log" in entry.tags:
topics_with_log_tag.append(topic)

get_topics_with_log_tag(topics)

它抛出语法错误:
SyntaxError: no binding for nonlocal 'topics_with_log_tag' found

其实我确实绑定(bind)了 topics_with_log_tag = []
上面的代码可以以冗余方式重写为
topics = Topic.objects.all()
#select entries with log tag
def get_topics_with_log_tag(topics):
# nonlocal topics_with_log_tag
topics_with_log_tag = []
for topic in topics:
for entry in topic.entry_set.all():
if "#log" in entry.tags:
topics_with_log_tag.append(topic)
return topics_with_log_tag

topics_with_log_tag = get_topics_with_log_tag(topics)

我使用 nonlocal 有什么问题? ?

我发现了错误。

Willem Van Onsem 引入了数据库级过滤器,而不是嵌套的 for 循环。

模型.py
 class Topic(models.Model):
"""A topic the user is learning about."""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User)

def __str__(self):
"""Return a string representation of the model."""
return self.text

class Entry(models.Model):
"""Something specific learned about a topic"""
topic = models.ForeignKey(Topic)
title = models.CharField(max_length=200)
text = models.TextField()
tags = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)

最佳答案

如何nonlocal作品

如果您使用 nonlocal ,这意味着 Python 将在函数的开头,从上面(和更远)的一个作用域中查找具有相同名称的变量。但是在这里你没有定义这样一个。我们可以通过定义一个更高的级别来修复它:

def log(request):
"""Show all topics and entries with log tags"""

topics = Topic.objects.all()
#select entries with log tag
topics_with_log_tag = []
def get_topics_with_log_tag(topics):
nonlocal topics_with_log_tag
topics_with_log_tag = []
for topic in topics:
for entry in topic.entry_set.all():
if "#log" in entry.tags:
topics_with_log_tag.append(topic)

get_topics_with_log_tag(topics)

您可以使用 global在这种情况下,您不需要声明这样的变量(在这种情况下,它是在上层声明的),但这实际上也是一种反模式。

Django ORM 中的高效数据库查询

然而,您在此处执行过滤的方式通常效率很低:您首先在此处遍历所有 Topic s,然后对于每个主题,您执行一个额外的查询来获取所有 Entry s,然后对于每个 Entry你获取所有 Tag s,然后查看其中一个标签是否为 #log .现在假设您有 10 个主题,每个主题有 10 个条目,每个条目有 5 个标签。这会导致您在数据库级别执行 500 多个查询。我们可以构造一个过滤器,如:
topics_with_log_tag = Topics.objects.filter(entry__tags__contains='#log').distinct()

或更具可读性(括号用于允许多行表达式):
topics_with_log_tag = (Topics.objects
.filter(entry__tags__contains='#log')
.distinct())

请注意,上面将(就像您的代码一样)还包含带有 tags 的主题例如 '#logarithm' .它只检查它是否包含某个子字符串。为了防止这种情况,您将需要更高级的过滤或更好的标签表示(带有结束标记)。

例如,如果每个主题都以逗号结尾(如 '#foo,#bar,' ),那么我们可以查询 '#log,' .

我们还可以使用正则表达式并检查新的哈希字符或字符串的结尾。

关于django - `SyntaxError: no binding for nonlocal ' topics_with_log_tag ' found` 虽然它是有界的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50412193/

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