Python中的变量作用域存在问题

ran*_*its 0 python django

这个问题部分是由于我没有完全理解python中的作用域,所以我需要回顾一下.无论哪种方式,这是一个非常重要的代码片段,一直在我的Django测试应用程序崩溃.

这是一个片段:

@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')
Run Code Online (Sandbox Code Playgroud)

这里没有脑部手术,问题是我得到如下错误:

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

UnboundLocalError: local variable 'usergroup' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么用户组未绑定?如果它是未绑定的,那意味着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
Run Code Online (Sandbox Code Playgroud)

bob*_*nce 10

HttpResponseRedirect('/accounts/login')
Run Code Online (Sandbox Code Playgroud)

你正在创造但不归还它.流程继续到下一行,usergroup尽管从未因异常而被分配,但仍会引用该行.

except也很麻烦.一般来说,你永远不应该抓住"一切"(except:except Exception:),因为你可能会丢弃许多奇怪的条件,使调试变得非常困难.要么捕获您认为将在用户未登录时发生的特定异常子类,要么更好地使用if测试来查看它们是否已登录.(这不是一个特例.)

例如.通常在Django中:

if not request.user.is_authenticated():
    return HttpResponseRedirect('/accounts/login')
Run Code Online (Sandbox Code Playgroud)

或者如果您担心的是用户不在任何组中(使[0]失败):

groups= request.user.groups.all()
if len(groups)==0:
    return HttpResponseRedirect('/accounts/login')
usergroup= groups[0].name
Run Code Online (Sandbox Code Playgroud)