不久前我开始用Django编写Python。有时我会遇到奇怪的错误并且没有任何线索,为什么呢。所以,让我们从其中一个错误开始。
我有一个带两个功能的View。例如:
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 Exception中运行。第39行是视图函数的render_to_response,而不是新函数。
那么,为什么我的 new 函数调用了我的视图函数中的错误?真的,我没有线索。我来自C#所以我确定我没有得到一些特殊的Python规则,这使我编码错误。
更新:由于stackoverflow.com代码面板,这两个函数的缩进不正确。不关心它。
答案 0 :(得分:3)
问题是缩进
def view(request):
...
def new(request):
...
对于python:
是不同的def view(request):
...
def new(request):
...
你应该确保使用空格来缩进,python建议使用4个空格而不是tab
更新
问题在于网址:
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>[^\.]+)'
答案 1 :(得分:1)
错误肯定听起来像是在调用view_post
视图函数。你确定你的网址是正确的吗?或者两个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