2009-12-02 49 views
0

这个问题部分是由于我缺乏完全理解Python中的范围,所以我需要回顾一下。无论哪种方式,这是一个严重的微不足道的代码片断,在我的Django测试应用程序中不断崩溃。Python中变量作用域的问题

这里有一个片段:

@login_required 
def someview(request): 
try: 
    usergroup = request.user.groups.all()[0].name 
except: 
    HttpResponseRedirect('/accounts/login') 

if 'client' in usergroup: 
    stafflist = ProxyUserModel.objects.filter(groups__name='staff') 

无脑外科手术在这里,问题是我得到一个错误,如下列:

File "/usr/local/django/myapp/views.py", line 18, in someview 
    if 'client' in usergroup: 

UnboundLocalError: local variable 'usergroup' referenced before assignment 

我的问题在这里,为什么用户组绑定?如果它没有绑定,那意味着try语句在HttpResponseRedirect应该发生的时候会抛出一个异常,但它永远不会。相反,我得到一个HTTP 500错误,这有点令人困惑。

是的我可以编写更聪明的代码,并确保登录的用户肯定有一个与他们关联的组。但这不是一个生产应用程序,我只是想了解/学习Python/Django。为什么上述情况发生在没有与组关联的用户登录时,而不是重定向到登录页面?

在这种情况下,我有意登录作为不是一个组的一部分的用户。这意味着,上述代码应该抛出IndexError异常类似如下:

>>> somelist = [] 
>>> print somelist[0] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: list index out of range 

回答

10
HttpResponseRedirect('/accounts/login') 

你创造它,但没有返回它。流程继续到下一行,尽管从未被分配,但由于异常,它仍会引用usergroup

except也很麻烦。一般来说,你不应该捕捉到'一切'(except:except Exception:),因为在那里你可能会丢掉很多奇怪的条件,这使得调试非常困难。要么捕获您认为在用户未登录时发生的特定异常子类,要么使用if测试来确定它们是否已登录。 (这不是一个真正的例外情况。)

例如。在Django正常:

if not request.user.is_authenticated(): 
    return HttpResponseRedirect('/accounts/login') 

,或者如果你关注的是用户没有任何团体(使[0]失败):

groups= request.user.groups.all() 
if len(groups)==0: 
    return HttpResponseRedirect('/accounts/login') 
usergroup= groups[0].name 
+1

+1;但请注意,最后一个条件已经在'@login_required'装饰器中完成了 – Javier 2009-12-02 21:18:49

+0

我犯了同样的错误不止一次。出于某种原因,它只是*感觉*就像你不需要回报,但当然你会这样做。 – 2009-12-02 21:22:33

+0

不能同意更多彼得。我一直忘记它是一个类而不是实际的方法调用。感谢所有人。 – randombits 2009-12-03 00:32:26

0

尝试移动你,如果你内心的“客户”部分try块。或者,或者定义usergroup = None正上方的try。

0

在你有一个try…except套件和你想要的代码运行IFF 没有发生例外的情况下,这是一个好习惯如下编写代码:

try: 
    # code that could fail 
except Exception1: 
    # handle exception1 
except Exception2: 
    # handle exception2 
else: # the code-that-could-fail didn't 
    # here runs the code that depends 
    # on the success of the try clause