2012-11-23 34 views
29

Tôi muốn bắt một ValueError cụ thể, không chỉ bất kỳ ValueError nào.
tôi đã cố gắng somthing như thế này:Python: Bắt ngoại lệ cụ thể

try: maquina['WPF'] = macdat(ibus, id, 'WPF') 
except: ValueError, 'For STRING = ’WPF’, this machine is not a wind machine.': 
    pass 

Nhưng nó đặt ra một Lỗi Cú pháp: không thể gán cho chữ.
Sau đó, tôi đã cố gắng:

try: maquina['WPF'] = macdat(ibus, id, 'WPF') 
except ValueError, e: 
    if e != 'For STRING = ’WPF’, this machine is not a wind machine.': 
     raise ValueError, e 

Nhưng nó làm tăng ngoại lệ, ngay cả khi nó là một trong tôi muốn tránh.

+7

Bạn nhận được câu trả lời bên dưới, nhưng khi bạn nâng cao ngoại lệ, chỉ cần sử dụng 'nâng cao ': theo cách đó nếu ngoại lệ không được xử lý, bạn vẫn nhận được backtrace ngăn xếp ban đầu thay vì bắt đầu từ đó được nâng lên. – Duncan

Trả lời

37

trong except ValueError,e, e là một trường hợp ngoại lệ, không phải là một chuỗi. Vì vậy, khi bạn kiểm tra nếu e không bằng một chuỗi cụ thể, kiểm tra đó luôn là Sai. Hãy thử:

if str(e) != "..." 

thay thế.

Ví dụ:

def catch(msg): 
    try: 
     raise ValueError(msg) 
    except ValueError as e: # as e syntax added in ~python2.5 
     if str(e) != "foo": 
      raise 
     else: 
      print("caught!") 

catch("foo") 
catch("bar") 

Thông thường, bạn không thực sự muốn dựa vào các thông báo lỗi nếu bạn có thể giúp nó - Đó là một chút quá mong manh. Nếu bạn có quyền kiểm soát callable macdat, thay vì nuôi một ValueError trong macdat, bạn có thể nâng cao một ngoại lệ tùy chỉnh mà thừa hưởng từ ValueError:

class MyValueError(ValueError): pass 

Sau đó, bạn chỉ có thể bắt MyValueError và để ValueError s khác tiếp tục trên con đường của họ bị bắt bởi cái gì khác (hay không). Đơn giản except ValueError vẫn sẽ bắt loại ngoại lệ này vì vậy nó sẽ hoạt động giống nhau trong mã khác mà cũng có thể bắt được ValueErrors từ hàm này.

+0

Đó là những gì tôi muốn. Cảm ơn sự giúp đỡ và đề nghị của bạn. –

+1

Thuộc tính 'Exception.message' đã biến mất trong Python 3, bạn có thể cập nhật câu trả lời của mình để phản ánh điều đó và đề xuất một thay thế (ví dụ,' str (e) ')? Câu hỏi này là bản sao chính tắc tốt cho loại câu hỏi này – vaultah

+1

@vaultah - Cảm ơn vì điều đó. Tôi đã cập nhật. – mgilson

3

Phương pháp cuối cùng là chính xác (nhưng in repr (e) để xem tại sao nó không hoạt động).

Tuy nhiên, nếu bạn muốn thông tin ngoại lệ là chính xác, bạn không nên tăng ngoại lệ mới (như bạn làm bây giờ), nhưng hãy tăng cùng một ngoại lệ. Nếu không, nhiều mã đánh bắt nó, hoặc thông báo lỗi nếu nó không bị bắt, sẽ hiển thị mã của bạn như là nguồn, trong khi nó phải là nguồn gốc.

Để thực hiện việc này, hãy sử dụng tăng mà không có đối số (trong khối ngoại trừ, dĩ nhiên, nếu không không có ngoại lệ "hiện tại").

Các vấn đề liên quan