Как правильно обрабатывать KeyboardInterrupt (Ctrl -c )с помощью pycurl?

Я пишу скрипт Python, используяpycurlдля использования Sreaming API Twitter . Вот короткий фрагмент, который делает именно это (просто введите свой логин/пароль Twitter, чтобы проверить его):

import pycurl

user = 'USER'
password = 'PWD'

def handleData(data):
    print(data)

conn = pycurl.Curl()  
conn.setopt(pycurl.USERPWD, "%s:%s" % (user, password))  
conn.setopt(pycurl.URL, 'https://stream.twitter.com/1/statuses/sample.json')  
conn.setopt(pycurl.WRITEFUNCTION, handleData)
conn.perform()

Проблема в том, что, поскольку скрипт потребляет поток, conn.perform()никогда не возвращает (или очень редко возвращает ). Таким образом, мне иногда нужно прерывать скрипт, а KeyboardInterruptловится методом perform().

Однако он плохо справляется с этим, выводит уродливую ошибку и вызывает другое исключение.

^CTraceback (most recent call last):
  File "test.py", line 6, in handleData
    def handleData(data):
KeyboardInterrupt
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    conn.perform()
pycurl.error: (23, 'Failed writing body (0 != 2203)')

В cURL FAQ говорится, что для прерывания текущей передачи одна из функций обратного вызова (в моем случаеhandleData)должен возвращать специальное значение. Это здорово, но KeyboardInterruptне перехватывается ни одной функцией обратного вызова!

Как я могу сделать это аккуратно?

РЕДАКТИРОВАТЬ :Я знаю, что вы можете перехватывать исключения, но pycurl все еще делает некоторые забавные вещи:

Если я это сделаю:

try:
    conn.perform()
except BaseException as e:
    print('We caught the exception')
    print(type(e))

я получаю:

^CTraceback (most recent call last):
  File "test.py", line 6, in handleData
    def handleData(data):
KeyboardInterrupt
We caught the exception
<class 'pycurl.error'>

Это означает, что внутренне pycurlвыполняет какую-то перехватку, печатает уродливое сообщение об ошибке, а затем вызывает pycurl.error.

7
задан bitek 17 December 2012 в 13:47
поделиться