2010-01-22 13 views
9

विकल्प 1:कौन सी शैली को प्राथमिकता दी जाती है?

def f1(c): 
    d = { 
    "USA": "N.Y.", 
    "China": "Shanghai" 
    } 

    if c in d: 
    return d[c] 

    return "N/A" 

विकल्प 2:

def f2(c): 
    d = { 
    "USA": "N.Y.", 
    "China": "Shanghai" 
    } 

    try: 
    return d[c] 
    except: 
    return "N/A" 

ताकि मैं तो कॉल कर सकते हैं:

for c in ("China", "Japan"): 
    for f in (f1, f2): 
    print "%s => %s" % (c, f(c)) 

विकल्प या तो निर्धारित करने के लिए कुंजी पहले से निर्देशिका में है (एफ 1), या बस अपवाद के लिए फॉलबैक (एफ 2)। किसको प्राथमिकता दी जाती है? क्यूं कर?

+8

को छोड़कर: खराब कर्म है। हमेशा पकड़ने में आपकी रुचि रखने के बारे में विशिष्ट रहें, इस मामले में KeyError – richo

+2

आपने एक खराब उदाहरण चुना है। स्पष्ट उत्तर में न तो शैली शामिल है। – Omnifarious

उत्तर

9

आम तौर पर, अपवाद कुछ ओवरहेड लेते हैं, और वास्तव में 'असाधारण' मामलों के लिए हैं। इस मामले में, यह निष्पादन के सामान्य भाग की तरह लगता है, न कि 'असाधारण' या 'त्रुटि' स्थिति।

सामान्यतः, मुझे लगता है कि आपका कोड "if/else" सम्मेलन का उपयोग करके लाभान्वित होगा, और केवल तभी अपवादों को सहेजने के लिए जब उन्हें वास्तव में आवश्यकता होगी।

+2

जो मुझे "जैसा लगता है कोड" याद दिलाता है, "चीजें बेहतर होती हैं क्योंकि उन्होंने डिजाइन किया है"। इसलिए मैं इसे उत्तर के रूप में चिह्नित करता हूं। –

+0

जब आप कहते हैं कि अपवाद एक ओवरहेड के साथ आते हैं तो आप सही हो सकते हैं, लेकिन पाइथन शैली 'अनुमति से क्षमा मांगना बेहतर है'। इसका मतलब है कि आप जांच नहीं करते हैं कि कुछ है या नहीं। आप कोशिश करें और इसे करें और बाद में क्षमा मांगें। अगर यह मैं था, तो मैं 'कोशिश/छोड़कर' –

+2

के साथ गया होगा यह एक अच्छा बिंदु जेफोज़ है। चीज़ों को आजमाएं और देखें कि क्या काम करता है, यह पाइथन में स्मार्ट है। हालांकि इस मामले में कोशिश/छोड़कर खंड का उपयोग करते समय जब हम असाधारण कुछ भी उम्मीद नहीं करते हैं तो यह एक अच्छा विचार नहीं है। रिचो की तरह कहा: "बुरा कर्म"।:-) –

21

न तो, मैं के लिए

def f2(c): 
    d = { 
    "USA": "N.Y.", 
    "China": "Shanghai" 
    } 

    return d.get(c, "N/A") 

इस तरह कम है और "मिल" इस काम के लिए डिज़ाइन किया गया है जाना होगा।

इसके अलावा एक स्पष्ट अपवाद के अलावा एक बुरा प्रैटिस है, इसलिए except KeyError: का उपयोग न केवल छोड़कर करें।

अपवादों में अजगर में अधिक ओवरहेड नहीं है। यदि बेहतर विकल्प नहीं होते हैं या कभी-कभी जब यह एक विशेषता लुकअप (हैशर के बजाय उपयोग करने के लिए) बचाता है तो आमतौर पर उनका उपयोग करना बेहतर होता है।

संपादित करें: अपवादों के बारे में सामान्य बिंदु को साफ़ करने के लिए।

पक्सडीब्लो सामान्य बिंदु पर सही है। पाइथन मुख्य रूप से "क्षमा मांगने के लिए आसान है" के लिए डिज़ाइन किया गया है। मैं कोशिश करता हूं कि क्या विफल रहता है (अपवाद), फिर "लीप से पहले देखो" देखें कि वहां क्या है और फिर आवेदन करें। ऐसा इसलिए है क्योंकि पाइथन में विशेषता लुकअप महंगा हो सकता है, इसलिए एक ही सामान को फिर से कॉल करना (सीमाओं की जांच करना) संसाधनों का अपशिष्ट है। हालांकि, पाइथन में आंतरिक सामान को सामान्य रूप से अच्छे मददगार मिलते हैं ताकि उनका उपयोग बेहतर हो।

+0

प्रश्न dict के लिए विशिष्ट नहीं है, यह मुख्य रूप से प्रदर्शन के लिए है। मैं क्या जानना चाहता हूं हाथ से पहले सीमाओं की जांच करना या अपवाद के लिए पीछे हटना। –

+1

@Dyno: तो आपको * * * से पूछा जाना चाहिए था। अंगूठे का एक अच्छा नियम "अनुमति से क्षमा मांगना बेहतर है", लेकिन मैं यह जोड़ूंगा कि यदि आम मामला माफी मांगने के परिणामस्वरूप होगा, तो आपको पहले माफी मांगनी चाहिए। –

+0

क्या आपका मतलब है "बस इसे करें"। यदि यह गलत हो जाता है, तो बाद में इसके साथ सौदा करें? –

7

न तो।

return d.get(c, 'N/A') 
11

सामान्य शब्दों में (जरूरी नहीं अजगर), मैं सभी में "ट्राई-तो-बताओ मुझे-अगर यह चला गया-गलत" विधि (अपवाद) लेकिन सरलतम मामलों पसंद करते हैं। ऐसा इसलिए है क्योंकि, थ्रेडेड वातावरण में या डेटाबेस पहुंच के दौरान, अंतर्निहित डेटा कुंजी जांच और मूल्य निष्कर्षण के बीच बदल सकता है।

यदि आप वर्तमान धागे के बाहर सहयोगी सरणी नहीं बदल रहे हैं, तो आप "चेक-फर्स्ट-फिर-निकालें" विधि कर सकते हैं।

लेकिन यह सामान्य मामले के लिए है।

return d.get (c, "N/A") 

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

+------------------------------+--------------------+ 
| Thread1      | Thread2   | 
+------------------------------+--------------------+ 
| Check is NY exists as a key. |     | 
|        | Delete NY key/val. | 
| Extract value for NY.  |     | 
+------------------------------+--------------------+ 

धागा 1 प्रयास मान प्राप्त करने के है, यह वैसे भी एक अपवाद मिल जाएगा, तो आप संभावना के लिए भी सिर्फ कोड और प्रारंभिक जांच निकाल सकते हैं।

डेटाबेस के बारे में टिप्पणी भी प्रासंगिक है क्योंकि यह एक और स्थिति है जहां अंतर्निहित डेटा बदल सकता है। यही कारण है कि मैं चाबियों की सूची प्राप्त करने के बजाय परमाणु एसक्यूएल (जहां संभव हो) पसंद करना चाहता हूं, फिर व्यक्तिगत विवरणों के साथ उन्हें संसाधित करना।

+0

मैंने हमेशा उन्हें बुलाया। माफी मांगना आसान है "और" क्रमशः आपको छलांग लगाने से पहले देखो "। लेकिन मैं पाइथन क्षमा में सहमत हूं जो आप के बाद हैं। –

+0

मैं इस दोनों को और jweede को उत्तर के रूप में चिह्नित करता हूं, लेकिन ऐसा लगता है कि यह करने योग्य नहीं है। –

4

मैं इस पर डेविड के साथ कर रहा हूँ:

def f2(c): 
    d = { 
     "USA": "N.Y.", 
     "China": "Shanghai" 
     } 

    return d.get(c, "N/A") 

... ठीक है मैं इसे कैसे लिखना चाहते हैं।

अपने अन्य विकल्पों को संबोधित करने के लिए:

में 'f1()', इस के साथ कुछ भी गलत नहीं है, दर असल, लेकिन शब्दकोशों काफी इस सटीक उपयोग के मामले के लिए एक विधि प्राप्त() है: "से मिलता है ताना, और यदि यह वहां नहीं है, तो इसके बजाय इस दूसरी चीज को वापस करें "। यह सब आपका कोड कह रहा है,() का उपयोग करके बस अधिक संक्षिप्त है।

'f2()' में, 'छोड़कर' का उपयोग करके स्वयं को छोड़कर, और इसके अलावा, आप वास्तव में अपवाद के जवाब में कुछ भी उपयोगी नहीं करते हैं - आपके मामले में कॉलिंग कोड कभी नहीं होगा पता था कि एक अपवाद था। तो निर्माण का उपयोग क्यों करें यदि यह आपके फ़ंक्शन या कोड को कॉल करने वाला मान नहीं जोड़ता है?

1

मैं लोगों को "पाने" का उपयोग करके देखता हूं, जो मैं अनुशंसा करता हूं।

try: 
    return d[k] 
except KeyError: 
    return "N/A" 

इस तरह, (KeyboardInterrupt सहित) अन्य अपवाद पकड़ा नहीं मिलता: हालाँकि, यदि आप भविष्य में इसी तरह की स्थिति में पाते हैं, तो अपवाद तुम्हारा मतलब पकड़ने। आप लगभग KeyboardInterrupt पकड़ना नहीं चाहते हैं।

0

मैं मानता हूं कि इस मामले में, dict.get सबसे अच्छा समाधान है।

सामान्यतः, मुझे लगता है कि आपकी पसंद इस बात पर निर्भर करेगी कि अपवाद कितने संभावित हैं। यदि आप मुख्य लुकअप को अधिकतर पास करने की अपेक्षा करते हैं, तो कोशिश/पकड़ बेहतर विकल्प आईएमओ है। इसी प्रकार, यदि वे अक्सर असफल हो जाएंगे, तो यदि एक कथन बेहतर है।

अपरिवर्तनीय प्रदर्शन बनाम विशेषता लुकअप पाइथन में इतना अलग नहीं है, इसलिए मैं प्रदर्शन पहलुओं के मुकाबले अपवाद/देखो-पहले-आप-लीप का उपयोग करने के तर्क के बारे में अधिक चिंता करता हूं।

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

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