0

不久前,我开始使用 Django 编写 Python。有时我会遇到奇怪的错误并且不知道为什么。所以,让我们从这些错误之一开始。

我有一个具有两个功能的视图。例子:

def view_post(request, slug):
    """
    Shows a single post
    """
    posts = Post.objects(slug = slug).limit(1)
    for items in posts:
        post = items

    cssClasses = css_class_converter({ _css_class_editable })

    context = RequestContext(request)
    return render_to_response("single.html", { 'post': post, 'class': cssClasses }, context)

def new_post(request):
    '''
    Opens a blank page for creating a new post
    '''

    post = Post()
    cssClasses = css_class_converter({ _css_class_editable, _css_class_new })
    context = RequestContext(request)
    return render_to_response("single.html", {'post': post, 'new': True }, context)

然后用我的 URLconf 调用它们。调用 view_post 函数可以正常工作,没有错误。

urlpatterns = patterns('blog.views',
    # Examples:
    url(r'^$', views.index),
    url(r'^(?P<slug>[^\.]+)', 'view_post', name='view_blog_post'),
    url(r'^new/$', 'new_post', name='new_blog_post'),

...

但是调用 new_post 函数会在第 39 行"local variable 'post' referenced before assignment"的 UnboundLocalError 异常中运行。第 39 行是视图函数的 render_to_response,而不是新函数。

那么,为什么我对新函数的调用会在我的视图函数中引发错误?真的,我一点头绪都没有。我是从 C# 过来的,所以我确定我没有得到一些特殊的 Python 规则,这使我编码错误。

更新:由于 stackoverflow.com 代码面板,这两个函数的缩进不正确。别管它。

在此处输入图像描述

4

2 回答 2

3

问题是缩进

def view(request):
    ...
    def new(request):
        ...

与python不同的是:

def view(request):
    ...

def new(request):
    ...

您应该确保使用空格进行缩进,python 建议使用 4 个空格而不是制表符

更新:

问题出在网址中:

url(r'^$', views.index),
url(r'^(?P<slug>[^\.]+)', 'view_post', name='view_blog_post'),
url(r'^new/$', 'new_post', name='new_blog_post'),

将其更改为:

url(r'^$', views.index),
url(r'^new/$', 'new_post', name='new_blog_post'),
url(r'^(?P<slug>[^\.]+)', 'view_post', name='view_blog_post'),

那是因为 url /new/ 匹配正则表达式

r'^(?P<slug>[^\.]+)'
于 2011-11-16T21:28:56.303 回答
1

该错误绝对听起来像是view_post正在调用视图函数。你确定你的 urlpatterns 是正确的吗?或者两个 URL 正则表达式都可以指向view_post.

如果view_post查询没有找到任何项目,那么仅在 for 循环中设置的变量post将不会被设置,并且对它的引用render_to_response将引发UnboundLocalError.

您可以通过在循环之前将 post 设置为 None 来避免这种情况。

def view_post(request, slug):
        """
        Shows a single post
        """
        posts = Post.objects(slug = slug).limit(1)
        post = None   # Ensure post is bound even if there are no posts matching slug
        for items in posts:
            post = items

        cssClasses = css_class_converter({ _css_class_editable })

        context = RequestContext(request)
        return render_to_response("single.html", { 'post': post, 'class': cssClasses }, context)

您可以使用这个更简单的函数了解为什么会发生 UnboundLocalError:

def first_element(items):
    for item in items:
        result = item
        break
    return result

(显然,您不会真正first_element像这样实现,但这说明了正在发生的事情。)如果您first_element使用非空列表调用,它将按预期工作:

>>> first_element([2, 3, 4])
2

但是如果你用一个空列表调用它,结果永远不会被绑定,所以你会得到错误:

>>> first_element([])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in first_element
UnboundLocalError: local variable 'result' referenced before assignment
于 2011-11-16T21:34:57.203 回答