调用不同函数时出现 Python Django UnboundLocalError

发布于 2024-12-16 01:42:30 字数 1488 浏览 1 评论 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 行“赋值之前引用的局部变量‘post’”出现 UnboundLocalError 异常。第39行是视图函数的render_to_response,而不是新函数。

那么,到底为什么我对 new 函数的调用会在我的 view 函数中抛出错误?真的,我不知道。我是从 C# 过来的,所以我确信我没有得到一些特殊的 Python 规则,这些规则会让我编码错误。

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

在此处输入图像描述

Not long ago I started programming Python with Django. Sometimes I get strange errors and have no clue, why. So, let's beginn with one of these errors.

I have a View with two functions. Example:

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)

Then calling them with my URLconf. Calling view_post function works as It should, without errors.

urlpatterns = patterns('blog.views',
    # Examples:
    url(r'^

But calling the new_post function runs in a UnboundLocalError Exception on line 39 "local variable 'post' referenced before assignment". Line 39 is render_to_response of the view function, not the new function.

So, why the heck is my call of the new function throwing an error in my view function? Really, I have no clue. I came over from C# so I'm sure I didn't get some special Python rule which makes me coding things wrong.

Update: The indentation of the two functions isn't correct because of stackoverflow.com code panel. Don't care about it.

enter image description here

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

But calling the new_post function runs in a UnboundLocalError Exception on line 39 "local variable 'post' referenced before assignment". Line 39 is render_to_response of the view function, not the new function.

So, why the heck is my call of the new function throwing an error in my view function? Really, I have no clue. I came over from C# so I'm sure I didn't get some special Python rule which makes me coding things wrong.

Update: The indentation of the two functions isn't correct because of stackoverflow.com code panel. Don't care about it.

enter image description here

, 'new_post', name='new_blog_post'), ...

But calling the new_post function runs in a UnboundLocalError Exception on line 39 "local variable 'post' referenced before assignment". Line 39 is render_to_response of the view function, not the new function.

So, why the heck is my call of the new function throwing an error in my view function? Really, I have no clue. I came over from C# so I'm sure I didn't get some special Python rule which makes me coding things wrong.

Update: The indentation of the two functions isn't correct because of stackoverflow.com code panel. Don't care about it.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦言归人 2024-12-23 01:42:30

问题是缩进

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

对于 python 来说是不同的:

def view(request):
    ...

def new(request):
    ...

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

更新:

问题出在 url 中:

url(r'^

将其更改为:

url(r'^

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

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

将其更改为:


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


, 'new_post', name='new_blog_post'),

将其更改为:


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


, views.index),
url(r'^new/

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


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

将其更改为:


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


, 'new_post', name='new_blog_post'),

将其更改为:

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

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

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

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

将其更改为:

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

, 'new_post', name='new_blog_post'),

将其更改为:

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

The problem is the indentation

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

Is different for python of:

def view(request):
    ...

def new(request):
    ...

You should be sure use spaces for indentation and python recommends 4 spaces instead of tab

Update:

The problem is in urls:

url(r'^

Change it to:

url(r'^

That is because the url /new/ match the regexp

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

Change it to:


That is because the url /new/ match the regexp


, 'new_post', name='new_blog_post'),

Change it to:


That is because the url /new/ match the regexp


, views.index),
url(r'^new/

That is because the url /new/ match the regexp


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

Change it to:


That is because the url /new/ match the regexp


, 'new_post', name='new_blog_post'),

Change it to:

That is because the url /new/ match the regexp

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

That is because the url /new/ match the regexp

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

Change it to:

That is because the url /new/ match the regexp

, 'new_post', name='new_blog_post'),

Change it to:

That is because the url /new/ match the regexp

南…巷孤猫 2024-12-23 01:42:30

该错误听起来肯定像是正在调用 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

The error definitely sounds like the view_post view function is being called. Are you sure that your urlpatterns are the right way around? Or both URL regexes could be pointed at view_post.

In view_post if the query finds no items, then the variable post that is only set in the for loop will not have been set, and the reference to it in render_to_response will raise the UnboundLocalError.

You can avoid that by setting post to None before the loop.

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)

You can see why the UnboundLocalError is happening using this simpler function:

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

(Obviously, you wouldn't really implement first_element like this, but this illustrates what's happening.)
If you call first_element with a non-empty list, it'll work as expected:

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

But if you call it with an empty list, result has never been bound, so you'll get the error:

>>> 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文