2012-06-28 12 views
14

हैंडलिंग एक छोटी पायथन में अपवाद हैंडलिंग के बारे में किसी के साथ बहस के बाद - एक कतार वस्तु की हैंडलिंग से तेज - मैंने सोचा कि मैं इसे बाहर वहाँ फेंक होगी ...पायथन: Queue.Empty अपवाद

विधि 1:

import Queue 

q = Queue.Queue() 

try: 
    task=q.get(False) 
    #Opt 1: Handle task here and call q.task_done() 
except Queue.Empty: 
    #Handle empty queue here 
    pass 

#Opt2: Handle task here and call q.task_done() 

विधि 2:

import Queue 

q = Queue.Queue() 

if q.empty(): 
    #Handle empty queue here 
else: 
    task = q.get() 
    #Handle task here 
    q.task_done() 

एक तर्क है कि विधि 1 गलत है क्योंकि कतार खाली किया जा रहा है कोई त्रुटि नहीं है, और इसलिए Queue.Empty अपवाद का उपयोग नहीं संभाला जाना चाहिए है। इसके अतिरिक्त, यदि आप मानते हैं कि कार्य हैंडलिंग भाग संभावित रूप से बड़ा हो सकता है तो यह डीबगिंग को और अधिक कठिन बना सकता है।

अन्य तर्क यह है कि किसी भी तरह से अजगर में और कहा कि स्वीकार्य है है की कोशिश के बाहर काम से निपटने/छोड़कर अगर काम से निपटने बड़ी है डीबगिंग, सहायता कर सकता है, हालांकि सहमति इस विधि 2.

का उपयोग करने से भद्दा लग सकता है कि

राय?

अपडेट: उत्तर 1 के बाद थोड़ी अधिक जानकारी के माध्यम से आया .... कुछ मल्टीथ्रेड कोड में विधि 1 का उपयोग करने के बाद बहस शुरू की गई थी। इस मामले में, कोड लॉक (थ्रेडिंग.लॉक ऑब्जेक्ट से) प्राप्त करेगा और इसे या तो लौटाए जाने के बाद या क्यूई को छोड़ देगा। लक्षण

अपडेट 2: यह दोनों के लिए अज्ञात था कि कतार वस्तु धागा सुरक्षित था। ऐसा लगता है कि जाने का तरीका है/छोड़ना!

+1

मुझे नहीं लगता कि लॉक उत्तर कैसे बदलता है, मुझे यह भी समझ में नहीं आता कि इसे लॉक की आवश्यकता क्यों है, कतार पहले ही थ्रेड-सुरक्षित है। –

उत्तर

26

विधि 2 गलत है क्योंकि आप दो चरणों में एक ऑपरेशन कर रहे हैं जब इसे एक में किया जा सकता है। विधि 2 में, आप जांचते हैं कि कतार खाली है या नहीं, और बाद में (बहुत जल्द, लेकिन बाद में बाद में), आइटम प्राप्त करने का प्रयास करें। क्या होगा यदि आपके पास कतार से वस्तुओं को खींचने के दो धागे हैं? Get() अभी भी एक खाली कतार के साथ असफल हो सकता है। क्या होगा यदि आपने यह चेक करने के बाद कतार में कोई आइटम जोड़ा है तो यह खाली था? ये मौके की छोटी खिड़कियां हैं जहां बग समवर्ती कोड में रेंगते हैं।

इसे एक ही चरण में करें, यह अब तक बेहतर विकल्प है।

import Queue 

q = Queue.Queue() 

try: 
    task = q.get(False) 
except Queue.Empty: 
    # Handle empty queue here 
    pass 
else: 
    # Handle task here and call q.task_done() 

"अपवादों को त्रुटियों में होना चाहिए" पर लटका नहीं है। अपवाद केवल संचार का एक और चैनल हैं, उनका उपयोग करें। अपवाद खंड के दायरे को कम करने के लिए यहां "अन्य" खंड का उपयोग करें।

3

यदि यह बहु/multiprocessed कोड है (के रूप में वैसे भी कतारों का उपयोग कर के लिए एक अच्छा कारण नहीं है), तो निश्चित रूप से विधि 1. बीच q.empty() कॉल और q.get() कॉल, पान के गुलाम अपने tarts चोरी किया जा सकता था!

+0

कुछ मल्टीथ्रेड कोड में विधि 1 का उपयोग करने के बाद बहस शुरू की गई थी। इस मामले में, कोड लॉक (थ्रेडिंग.लॉक ऑब्जेक्ट से) प्राप्त करेगा और इसे या तो लौटाए जाने के बाद या क्यूई को छोड़ देगा। लक्षण फेंक दिया गया है ...... एक ही राय? – user1014903

+0

त्रुटि-कोडिंग कोड को यथासंभव कसकर रखें - 'get'' पर कॉल करें और उसके बाद सीधे त्रुटि की जांच करें। कोशिश में शेष कोड एम्बेड करने की जरूरत नहीं है ... –

2

एक तर्क क्योंकि कतार खाली किया जा रहा है कोई त्रुटि नहीं है कि विधि 1 गलत है, और इसलिए Queue.Empty अपवाद

का उपयोग कर एक अपवाद आवश्यक रूप से "त्रुटि" नहीं है नहीं संभाला जाना चाहिए है , यह एक सामान्य प्रवाह नियंत्रण तंत्र है, और वास्तव में कुछ मामलों में इसका उपयोग किया जाता है (SysExit, StopIteration आदि)।

यहां अच्छा सवाल यह है कि: सबसे आम मामला - खाली या खाली खाली कतार क्या होगा। जब तक आप निश्चित रूप से नहीं जानते, आप पूछना चाहते हैं इससे पहले, क्योंकि यह शायद ही सस्ता है।

संबंधित मुद्दे