2012-02-25 19 views
26

Khi urllib2.request hết thời gian chờ, ngoại lệ urllib2.URLError được nâng lên. Cách pythonic để thử thiết lập kết nối là gì?Làm thế nào để thử lại urllib2.request khi không thành công?

+1

Câu hỏi này phải trả lời câu hỏi của bạn: http://stackoverflow.com/questions/2712524/handling-urllib2s-timeout-python –

+2

Tôi không hỏi làm cách nào để nắm bắt được yêu cầu. Tôi muốn biết nếu có một cách pythonic để thử lại thiết lập kết nối. – iTayb

+0

Xin lỗi, tôi cho rằng vấn đề là phát hiện thời gian chờ đã đạt được, không phải là tái hợp nhất kết nối. Bạn không thể gọi urlopen() trong khối ngoại lệ? –

Trả lời

52

Tôi sẽ sử dụng trình trang trí retry. Có những cái khác ngoài kia, nhưng cái này hoạt động khá tốt. Dưới đây là cách bạn có thể sử dụng:

@retry(urllib2.URLError, tries=4, delay=3, backoff=2) 
def urlopen_with_retry(): 
    return urllib2.urlopen("http://example.com") 

Điều này sẽ thử lại chức năng nếu URLError được nâng lên. Kiểm tra liên kết ở trên để biết tài liệu về các tham số, nhưng về cơ bản, nó sẽ thử lại tối đa 4 lần, với trễ trễ theo hàm mũ tăng gấp đôi mỗi lần, ví dụ: 3 giây, 6 giây, 12 giây.

+1

Đây là đoạn trích thực sự thú vị. Bạn có biết một sự thay thế, nhưng là một người quản lý ngữ cảnh? –

+0

Hmm, tôi nghĩ bạn có lẽ có thể viết lại nó như một người quản lý ngữ cảnh khá dễ dàng, nhưng tôi không có một tay. – jterrace

+0

Nó không dễ dàng để làm, vì không có cách dễ dàng để nắm bắt các khối bên trong với tuyên bố. Bạn cần một số nội tâm sâu sắc. –

3

Để thử lại vào thời gian chờ bạn có thể nắm bắt những ngoại lệ như @Karl Barker suggested in the comment:

assert ntries >= 1 
for _ in range(ntries): 
    try: 
     page = urlopen(request, timeout=timeout) 
     break # success 
    except URLError as err: 
     if not isinstance(err.reason, socket.timeout): 
      raise # propagate non-timeout errors 
else: # all ntries failed 
    raise err # re-raise the last timeout error 
# use page here 
4

Có một vài thư viện ra khỏi đó mà chuyên này.

Một là backoff, được thiết kế với độ nhạy đặc biệt chức năng. Trang trí được thông qua tùy ý gọi trở về máy phát điện mà mang lại giá trị chậm trễ liên tiếp. Một backoff mũ đơn giản với một thời gian retry tối đa 32 giây có thể được định nghĩa là:

@backoff.on_exception(backoff.expo, 
         urllib2.URLError, 
         max_value=32) 
def url_open(url): 
    return urllib2.urlopen("http://example.com") 

khác là retrying có chức năng rất giống nhau nhưng một API nơi thử lại các thông số được quy định bằng cách args từ khóa được xác định trước.

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