2015-09-16 12 views
6

Vì vậy, tôi có một lớp với hai phương pháp trong đó:Trở về từ bắt "RuntimeError" luôn mang đến cho 'python None`

class Test: 
    def cycle(self, n=float("inf"), block="x"): 
     try:    
      self.cycle(n-1, block) 
     except RuntimeError as e: 
      if str(e) == "maximum recursion depth exceeded": 
       print("... forever") 
       return 10 
    def f(self): 
     try: 
      raise Exception() 
     except: 
      return 10 
     return 20 


x = Test() 
print(x.cycle()) 
print(x.f()) 

và nó kết quả đầu ra:

... forever 
None 
10 

gì cho? Tại sao tôi có thể trở về từ một ngoại trừ người khác chứ? Tôi có thể in bình thường từ lần đầu tiên ngoại trừ, nhưng nó luôn luôn trả về None

+0

Hum, tôi chỉ thử đặt 'return 10' ra khỏi' ngoại trừ RuntimeError là e: '. Và nó hoạt động. –

Trả lời

4

Vì phương pháp cycle() là đệ quy, nhưng khi bạn gọi nó đệ quy, bạn không trả lại kết quả được trả về bởi cuộc gọi đệ quy.

Vì vậy, bên self.cycle(), cho phép nói bạn gọi self.cycle() một lần nữa, và sau đó trong khi đang cố gắng gọi self.cycle() các RuntimeError xảy ra, vì vậy cuộc gọi mà trả 10 trở lại self.cycle() cuộc gọi đầu tiên, nhưng điều này (cho phép nói đầu tiên self.cycle()) gọi thực hiện không trả về kết quả này lại cho người gọi của nó, do đó kết quả trả về bởi số thứ hai self.cycle() bị mất và bạn được trả về None.

Nếu bạn trả lại kết quả cuộc gọi self.cycle(), bạn sẽ nhận được kết quả chính xác. Ví dụ -

>>> import sys 
>>> sys.setrecursionlimit(3) 
>>> class Test: 
...  def cycle(self, n=float("inf"), block="x"): 
...   try: 
...    return self.cycle(n-1, block) 
...   except RuntimeError as e: 
...    if str(e) == "maximum recursion depth exceeded": 
...     print("... forever") 
...     return 10 
... 
>>> t = Test() 
>>> print(t.cycle()) 
... forever 
10 

Xin lưu ý, tôi đặt giới hạn đệ quy thành 3 để độ sâu đệ quy vượt quá lỗi xảy ra sau 3 lần đệ quy.

+0

Ah, thật ngớ ngẩn của tôi. Ở đây tôi nghĩ python có một cách xử lý phức tạp đặc biệt 'RuntimeError' khi nó đơn giản là một câu lệnh' return' bị bỏ sót. Cảm ơn bạn – River

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