2010-11-10 303 views
1

我已經很好地理解了python的try-except子句,但是在嘗試將它放入函數中時遇到了問題。Python嘗試 - 除了函數內部

>>> def tryAppend(child, parent): 
...  try: 
...    parent.append(child) 
...  except NameError: 
...    print "WRONG NAME" 
>>> var1 = [] 
>>> var2 = 'test2' 
>>> tryAppend(var2, var1) #works, no error 
>>> tryAppend(foo, var1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'foo' is not defined 

它幾乎就像python沒有看到try:語句。任何幫助表示讚賞。

+0

VAR2是字符串「test2的」命名空間。如果你想輸入一個字符串'foo',那麼你必須將其封裝在''或'「中,否則,如果foo沒有在程序中的其他地方作爲函數或類或其他函數定義,則不起作用。你基本上是在聲明它之前嘗試使用一個名稱空間。 – momo 2010-11-10 19:19:14

回答

5

這與您的異常處理程序無關。您看到的錯誤是因爲「foo」沒有在任何地方定義。

4

名稱錯誤在它進入tryAppend之前發生。它在嘗試將它傳遞給函數時評估foo的值。這個工作原理:

def tryAppend(child, parent): 
    parent.append(child) 

var1 = [] 
try: 
    tryAppend(foo, var1) 
except NameError: 
    print 'WRONG NAME' 
+0

謝謝喬納森。我不是那個評估變量的過程。所以這使得不可能將未定義的變量傳遞給函數,對吧?只是儘量使代碼儘可能乾淨.... – garen 2010-11-10 19:09:33

+0

如果您想將「未定義」變量傳遞給函數,您可以嘗試傳入locals()。 – 2010-11-10 19:11:50

+0

@garen:不要編寫引發NameErrors的代碼。確保它們總是在** all **代碼路徑中分配一些(明智的!)值,或者在最終導致不允許您繼續(有意義)的狀態時提前死亡並且發送有意義的錯誤消息。 – delnan 2010-11-10 19:17:50

2

當名字'foo'被評估時,在輸入函數之前引發NameError。因此,該函數內的try /除外是不相關的。

0

foo即使在您輸入函數tryAppend()(即函數之外)之前,也會發生異常。

8

我有蟒蛇的嘗試 - 除了條款

號井的一個很好的瞭解,也許你有,但你嚴重缺乏等,更重要的領域。無論您希望嘗試的(雙關不打算)範圍奇蹟般地擴展,或者您不明白代碼的評估順序是什麼......我將假設後者。 tryAppend(foo, var1)進行評估(大致)的順序:

  1. 抓取對象tryAppend引用
  2. 抓取對象foo引用
  3. 抓取對象var1引用
  4. 呼叫第一與第二和第三作爲參數(=做任何功能tryAppend,不包括嘗試除外)

錯誤或者在函數和try塊進入之前的#2發生。事實上,try塊不能拋出一個NameError,作爲唯一使用的名稱是parentchild,均爲參數,因此總是可用的(如果.append不存在,這是一個AttributeError)。

你問爲什麼

raise Exception("Catch me if you can") 
try: 
    pass # do nothing 
except: 
    print "caught it" 

不打印 「抓住它」。

+0

我是一個可怕的nitpicky人,我想說try塊可能會引發名稱錯誤,比如說,如果'parent.append'丟了一個。但這很愚蠢=)。 – katrielalex 2010-11-10 21:22:38

+0

@katriealex:你是對的......在挑剔的環境中:) – delnan 2010-11-10 21:52:53

0

對於正在尋找如何在功能內部使用除了構造之外的嘗試的人。 我不確定這是否是一種很好的編程風格,但它的工作原理。

您可以將字符串參數放入該函數。將正確評估,然後你可以使用exec的函數內:

def tryAppend(child, parent): 
    try: 
     script = parent + '.append(' + child + ')' 
     exec script 
     return parent 
    except NameError: 
     print "WRONG NAME" 
var1 = [] 
var2 = 'test2' 
tryAppend('var2', 'var1') 
tryAppend('foo', 'var1')