调用不同函数时出现 Python Django UnboundLocalError
不久前,我开始使用 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.
, 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.
, '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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是缩进
对于 python 来说是不同的:
您应该确保使用空格进行缩进,并且 python 建议使用 4 个空格而不是制表符
更新:
问题出在 url 中:
将其更改为:
那是因为 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
Is different for python of:
You should be sure use spaces for indentation and python recommends 4 spaces instead of tab
Update:
The problem is in urls:
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
该错误听起来肯定像是正在调用
view_post
视图函数。您确定您的 urlpatterns 是正确的吗?或者两个 URL 正则表达式都可以指向view_post
。在
view_post
中,如果查询没有找到任何项目,则仅在 for 循环中设置的变量post
将不会被设置,并且中对它的引用render_to_response
将引发UnboundLocalError
。您可以通过在循环之前将 post 设置为 None 来避免这种情况。
您可以使用这个更简单的函数了解为什么会发生 UnboundLocalError:(
显然,您不会真正像这样实现
first_element
,但这说明了正在发生的情况。)如果您使用非空列表调用
first_element
,它将按预期工作:但是如果您使用空列表调用它,则结果从未绑定,因此您将收到错误:
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 atview_post
.In
view_post
if the query finds no items, then the variablepost
that is only set in the for loop will not have been set, and the reference to it inrender_to_response
will raise theUnboundLocalError
.You can avoid that by setting post to None before the loop.
You can see why the UnboundLocalError is happening using this simpler function:
(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:But if you call it with an empty list, result has never been bound, so you'll get the error: