2016-01-11 13 views
5

में टूटे हुए पाइप को पकड़ें मैं टूटी हुई पाइप त्रुटि को पकड़ने के लिए कुछ कोड लिखने का प्रयास करता हूं। कोड पायथन 2.x और पायथन 3.x में चलाना चाहिए।पाइथन 2 और पायथन 3

अजगर 2.xa टूटी हुई पाइप में एक socket.error

socket.error: [Errno 32] Broken pipe 

यह अजगर 3.x में बदल गया था का प्रतिनिधित्व करती है - एक टूटी हुई पाइप अब एक BrokenPipeError

BrokenPipeError: [Errno 32] Broken pipe 

भी की वाक्य रचना है अपवाद हैंडलिंग थोड़ा बदल गया है (https://stackoverflow.com/a/34463112/263589 देखें) तो मुझे क्या करना होगा:

try: 
    do_something() 
except BrokenPipeError as e: # implies Python 3.x 
    resolve_for_python2() 
except socket.error as e: 
    if sys.version_info[0] == 2: # this is necessary, as in Python >=3.3 
           # socket.error is an alias of OSError 
           # https://docs.python.org/3/library/socket.html#socket.error 
     resolve_for_python3() 
    else: 
     raise 

वहां (कम से कम) एक शेष समस्या है: पायथन 2.x में BrokenPipeError नहीं है, इसलिए जब भी do_something() में कोई अपवाद होता है तो Python 2.x एक और अपवाद फेंक देगा और शिकायत करेगा कि यह BrokenPipeError नहीं जानता है। socket.error को पायथन 3.x में बहिष्कृत किया गया है इसी तरह की समस्या निकट भविष्य में पायथन 3.x में उत्पन्न हो सकती है।

यह कोड पायथन 2.x और पायथन 3.x में चलाने के लिए मैं क्या कर सकता हूं?

+0

http://python-future.org/compatible_idioms.html पर एक नज़र डालें, वे अपवाद हैंडलिंग दिखाते हैं। – MKesper

+1

http://newbebweb.blogspot.in/2012/02/python-head-ioerror-errno-32-broken.html यहां –

+0

धन्यवाद! लेकिन http://python-future.org/compatible_idioms.html#catching-exceptions यह बताता नहीं है कि अपवाद को कैसे पकड़ें जो कि पाइथन 2 या पायथन 3 में मौजूद नहीं है लेकिन दूसरे संस्करण में अनिवार्य है। – speendo

उत्तर

3

की तरह उपयोग तुम सब के बारे में परवाह कर रहे हैं टूटी हुई पाइप त्रुटियां, तो आप socket.error पकड़ सकते हैं और बस यह जांच सकते हैं कि यह वास्तव में टूटा हुआ पाइप त्रुटि है या नहीं।

आप अपवाद के errno विशेषता का उपयोग करके ऐसा कर सकते हैं, जो कि पाइथन 2 और पायथन 3 दोनों में मौजूद है, जिसका अर्थ है कि आपको अलग पायथन 2 बनाम 3 तर्क की आवश्यकता नहीं है (मैं तर्क दूंगा कि इरादा थोड़ा सा है स्पष्ट इस तरह से):

import socket 
import errno 


try: 
    do_something() 
except socket.error as e: 
    if e.errno != errno.EPIPE: 
     # Not a broken pipe 
     raise 
    do_something_about_the_broken_pipe() 

आप के बारे में टूटी हुई पाइप की तुलना में अधिक परवाह करते हैं, तो thefourtheye के जवाब उचित और मुहावरेदार है।

+0

धन्यवाद! यह मुझे थोड़ा चिंतित करता है कि 'socket.error' को पायथन 3 में बहिष्कृत किया गया है। इसलिए यदि मैं अपने पायथन 3 दुभाषिया को अद्यतन करता हूं, तो भविष्य में (निकट) भविष्य में एक और समस्या हो सकती है ... – speendo

+1

@speendo के दर्जनों संदर्भ हैं पाइथन मानक लाइब्रेरी में 'socket.error' * *। यह निश्चित रूप से बहिष्कृत है, लेकिन यह दूर नहीं जा रहा है। 'Socket.error' को हटाकर एक व्यर्थ तोड़ने वाला परिवर्तन होगा, जो कुछ है जो पाइथन कोर डेवलपर्स ने सार्वजनिक रूप से कहा है कि वे भविष्य में बचेंगे। अगर यह समाप्त हो गया (कुछ दशकों में ?!;)), त्रुटि पहचानने और ठीक करने के लिए तुच्छ होगी, और उस बिंदु पर आप शायद पाइथन 2 का समर्थन नहीं करेंगे। –

+0

समझ में आता है .... – speendo

1

आप BrokenPipeError उपयोग करने का प्रयास कर सकते हैं और अगर यह एक NameError फेंकता है, तो socket.error वापस करने के लिए आते हैं और इस

import socket 
try: 
    expected_error = BrokenPipeError 
except NameError: 
    expected_error = socket.error 

की तरह है, तो इस

try: 
    1 == 2 
except expected_error as ex: 
    # Handle the actual exception here 
संबंधित मुद्दे