Sto scrivendo uno script Python utilizzando pycurl
per consumare Twitter's Sreaming API. Ecco un breve frammento che fa esattamente questo (semplicemente mettere il vostro login Twitter/password per testarlo):Come gestire KeyboardInterrupt (Ctrl-c) bene con pycurl?
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()
Il problema è che perché lo script consuma un ruscello, conn.perform()
mai restituisce (o molto raramente). Pertanto, a volte ho bisogno di interrompere lo script e lo KeyboardInterrupt
viene catturato dal metodo perform()
.
Tuttavia, non gestisce bene, stampa un brutto errore e genera un'eccezione diversa.
^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)')
Il cURL FAQ dice che per interrompere un trasferimento in corso, una delle funzioni di callback (nel mio caso handleData
) dovrebbe restituire un valore speciale. Questo è ottimo, ma lo KeyboardInterrupt
non viene catturato da nessuna delle funzioni di callback!
Come posso fare questo ordinatamente?
EDIT: So che è possibile intercettare le eccezioni, ma pycurl fa ancora alcune cose divertenti:
Se lo faccio:
try:
conn.perform()
except BaseException as e:
print('We caught the exception')
print(type(e))
ottengo:
^CTraceback (most recent call last):
File "test.py", line 6, in handleData
def handleData(data):
KeyboardInterrupt
We caught the exception
<class 'pycurl.error'>
Ciò significa che internamente, pycurl
esegue un qualche tipo di rilevamento, stampa un brutto messaggio di errore e quindi solleva uno pycurl.error
.
'KeyboardInterrupt' [non è una sottoclasse di' Exception', è una sottoclasse di 'BaseException'] (http://docs.python.org/library/exceptions.html#exception-hierarchy) - tuttavia, ciò non modifica l'output. (Anche se un altro esempio del perché catturare l'eccezione è una cattiva idea.) –
Grazie per averlo indicato, ho corretto il mio esempio. Non cambia la mia domanda però. – Wookai
È necessario conn.close() dopo conn.perform(). –