2012-09-05 15 views
18

यह एक समस्या है जो Django प्रोजेक्ट पर काम करते समय मेरे पास आई थी। यह फॉर्म सत्यापन के बारे में है।पायथन: शॉर्ट सर्किट मूल्यांकन से बचें

Django में, जब आपके पास एक सबमिट किया गया फॉर्म है, तो आप is_valid() को संबंधित फॉर्म ऑब्जेक्ट पर सत्यापन ट्रिगर करने और एक बूलियन मान वापस करने के लिए कॉल कर सकते हैं। तो, आमतौर पर आपको लगता है कि आपके विचार कार्यों के अंदर की तरह कोड है:

if form.is_valid(): 
    # code to save the form data 

is_valid() न केवल प्रपत्र डेटा की पुष्टि करता है, लेकिन यह भी रूप उद्देश्य यह है कि बाद में उपयोगकर्ता के लिए प्रदर्शित किया जा सकता है के लिए त्रुटि संदेश कहते हैं।

एक पृष्ठ पर मैं एक साथ दो रूपों का उपयोग करता हूं और यह भी चाहता हूं कि डेटा केवल तभी सहेजा जा सके जब दोनों रूपों में वैध डेटा हो। इसका मतलब है कि मुझे डेटा को बचाने के लिए कोड निष्पादित करने से पहले दोनों रूपों पर is_valid() को कॉल करना होगा। सबसे स्पष्ट तरीका:

if form1.is_valid() and form2.is_valid(): 
    # ... 

लॉजिकल ऑपरेटरों के शॉर्ट सर्किट मूल्यांकन के कारण काम नहीं करेगा। यदि फॉर्म 1 मान्य नहीं है, तो फॉर्म 2 का मूल्यांकन नहीं किया जाएगा और इसके त्रुटि संदेश गायब होंगे।

यह केवल एक उदाहरण है। जहां तक ​​मुझे पता है, and/or अन्य भाषाओं में (यानी स्मॉलटॉक) के रूप में कोई लालची विकल्प नहीं है। मैं कल्पना कर सकता हूं कि विभिन्न परिस्थितियों में समस्या हो रही है (और न केवल पायथन में)। जिन समाधानों के बारे में मैं सोच सकता हूं वे सभी तरह के बेकार हैं (नेस्टेड आईएफएस, स्थानीय वैरिएबल को रिटर्न वैल्यू असाइन करना और यदि कथन में उनका उपयोग करना)। मैं इस तरह की समस्याओं को हल करने के लिए पाइथोनिक तरीका जानना चाहता हूं।

अग्रिम धन्यवाद!

उत्तर

27

कैसे की तरह कुछ के बारे में:

if all([form1.is_valid(), form2.is_valid()]): 
    ... 

एक सामान्य स्थिति में, एक सूची-समझ (के रूप में एक जनरेटर अभिव्यक्ति जो आमतौर पर इस संदर्भ में प्रयोग किया जाता है के खिलाफ) तो परिणाम सामने गणना कर रहे हैं इस्तेमाल किया जा सकता । उदा .:

if all([ form.is_valid() for form in (form1,form2) ]) 

यह रूप में अच्छी तरह की स्थिति का एक मनमाना संख्या के लिए अच्छी तरह से पैमाने होगा ... केवल पकड़ है कि वे सभी के रूप में करने का विरोध किया if foo and bar or baz: ... "and" द्वारा कनेक्ट करने की आवश्यकता है।

(गैर-शॉर्ट सर्किटिंग or के लिए, आप all के बजाय any का उपयोग कर सकते हैं)।

+0

बिल्कुल वही जो मैंने देखा था। धन्यवाद! – j0ker

+2

मुझे इसके साथ आने में कुछ सेकंड लगे। यह एक कोने का मामला है जिसे मैंने पहले नहीं माना था (मैं अक्सर फोर्ट्रान में काम करता हूं जो शॉर्ट-सर्किटिंग की गारंटी नहीं देता है, लेकिन इसे अनुमति देता है) और मैं हमेशा यह सुनिश्चित करने की कोशिश कर रहा हूं कि मेरी अभिव्यक्तियों को कम सर्किट किया जाए। यह पता लगाने के लिए मेरे लिए थोड़ा पीछे था :)। – mgilson

+0

हां 'सभी' यहां जाने का तरीका है, लेकिन आपने सूची-समझ का उपयोग कहां किया? मैं केवल आपके उदाहरण पर एक साधारण सूची देखता हूं। – rantanplan

16

आप बस बाइनरी & ऑपरेटर का उपयोग कर सकते हैं, जो बूल पर गैर-शॉर्ट-सर्किट लॉजिकल और करेगा।

if form1.is_valid() & form2.is_valid(): 
    ... 
+3

अधिक विशेष रूप से, यह पूर्णांक पर थोड़ा सा 'और' करेगा। चूंकि बूल 'ट्रू == 1' और' गलत == 0' 'के साथ पूर्णांक से प्राप्त किए जाते हैं, यह काम करता है। यह अन्य प्रकारों या कार्यों के लिए काम नहीं करेगा (जरूरी) जो उन चीजों को वापस लौटाते हैं जो बुलियन नहीं हैं। फिर भी, यह एक अच्छा टूल है (+1) – mgilson

+1

mgilson द्वारा समाधान से निश्चित रूप से सरल है। उसके लिए धन्यवाद! अन्य लोग कोड पढ़ने वाले अन्य लोगों के लिए और अधिक सहायक हो सकते हैं। यहां, मुझे लगता है कि आप सोच सकते हैं कि मैंने अभी 'और' और '&' उलझन में है। – j0ker

+0

@ मिगिलसन 'ऑल' फ़ंक्शन भी पहला समाधान था जो मेरे दिमाग में आया था (मैं इसका उल्लेख उसी कारण के लिए करता हूं जो कि जे0ker ने उल्लेख किया है), लेकिन मैंने उस उत्तर के लिए देर से सवाल खोजा (+1, बीटीडब्ल्यू) :-) – sloth

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