2009-12-02 46 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