Tôi đang viết một tập lệnh Python sử dụng pycurl
để tiêu thụ Twitter's Sreaming API. Dưới đây là một đoạn ngắn mà không chính xác điều đó (chỉ cần đặt Twitter đăng nhập của bạn/mật khẩu để kiểm tra nó):Làm thế nào để xử lý KeyboardInterrupt (Ctrl-c) độc đáo với 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()
Vấn đề là vì kịch bản tiêu thụ một dòng suối, conn.perform()
không bao giờ trở lại (hoặc rất hiếm khi). Do đó, đôi khi tôi cần phải ngắt đoạn mã và KeyboardInterrupt
bị bắt theo phương thức perform()
.
Tuy nhiên, nó không xử lý tốt, in ra lỗi xấu và tăng ngoại lệ khác.
^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)')
Các cURL FAQ nói rằng để làm gián đoạn một chuyển đang diễn ra, một trong những chức năng gọi lại (trong trường hợp của tôi handleData
) phải trả lại một giá trị đặc biệt. Điều này thật tuyệt, nhưng KeyboardInterrupt
không bị bắt bởi bất kỳ chức năng gọi lại nào!
Tôi có thể làm điều này gọn gàng như thế nào?
EDIT: Tôi biết rằng bạn có thể bắt ngoại lệ, nhưng pycurl vẫn hiện một số điều buồn cười:
Nếu tôi làm:
try:
conn.perform()
except BaseException as e:
print('We caught the exception')
print(type(e))
tôi nhận được:
^CTraceback (most recent call last):
File "test.py", line 6, in handleData
def handleData(data):
KeyboardInterrupt
We caught the exception
<class 'pycurl.error'>
Điều này có nghĩa rằng nội bộ, pycurl
thực hiện một số loại bắt, in một thông báo lỗi xấu xí và sau đó tăng một số pycurl.error
.
'KeyboardInterrupt' [không phải là một lớp con của 'Exception', đó là một lớp con của' BaseException'] (http://docs.python.org/library/exceptions.html#exception-hierarchy) - tuy nhiên, điều đó không thay đổi đầu ra. (Mặc dù một ví dụ khác về lý do tại sao bắt 'Ngoại lệ' là một ý tưởng tồi.) –
Cảm ơn bạn đã chỉ ra điều đó, tôi đã sửa lại ví dụ của mình. Nó không thay đổi câu hỏi của tôi mặc dù. – Wookai
Bạn cần conn.close() sau conn.perform(). –