'यदि' कथनों में स्टाइलिंग मल्टी-लाइन स्थितियाँ? [बन्द है]


675

कभी-कभी मैं ifकई लाइनों में लंबी स्थितियों को तोड़ता हूं । ऐसा करने का सबसे स्पष्ट तरीका है:

  if (cond1 == 'val1' and cond2 == 'val2' and
      cond3 == 'val3' and cond4 == 'val4'):
      do_something

नेत्रहीन बहुत आकर्षक नहीं है, क्योंकि कार्रवाई शर्तों के साथ मिश्रित होती है। हालाँकि, यह 4 स्थानों के सही पायथन इंडेंटेशन का उपयोग करने का प्राकृतिक तरीका है।

फिलहाल मैं इसका उपयोग कर रहा हूं:

  if (    cond1 == 'val1' and cond2 == 'val2' and
          cond3 == 'val3' and cond4 == 'val4'):
      do_something

लेकिन यह बहुत सुंदर नहीं है। :-)

क्या आप वैकल्पिक तरीका सुझा सकते हैं?


2
यदि आपका संपादक PEP8 उल्लंघनों के बारे में चेतावनी देने के लिए पता लगाने के लिए pep8 पायथन पैकेज का उपयोग करता है , तो आपको या तो E125 त्रुटि को अक्षम करना होगा या एक प्रारूपण समाधान खोजना होगा जो पैकेज के मानदंडों को पूरा करता है। पैकेज का मुद्दा # 126 सख्ती से PEP8 कल्पना का पालन करने के पैकेज फिक्सिंग के बारे में है। इस मुद्दे की चर्चा में कुछ शैली के सुझाव भी शामिल हैं जिन्हें यहाँ देखा गया है। pep8pep8
एकैहोला

1
ध्यान दें कि पहले उदाहरण के लिए, pep8 "E129 नेत्रहीन इंडेंटेड लाइन को अगले इंडेंट लाइन के समान इंडेंट के साथ फेंक देगा"।
टेलर एड्मिस्टन

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

@ Z4-tier: हाँ, यह राय आधारित है। लेकिन यह 12 साल पहले पूछा गया था। एसओ एक अलग, दयालु जगह था। हाल ही में यह एसओ के मानकों में बदलाव के बाद से डाउनवोट जमा हो रहा है। फिर भी, 1 मिलियन बार देखा गया है, मुझे उम्मीद है कि यह दुनिया में नुकसान की तुलना में अधिक अच्छा कर रहा है। मैं निश्चित रूप से लोगों को आज उसी प्रश्न के बारे में सोचता हुआ देख सकता हूं, इसे Googling, इस चर्चा पर उतरना और अपनी सोच को जांचने के लिए उपयोगी पा सकता हूं। चुनने के लिए कई उच्च मतदान जवाब हैं।
एली बेंडरस्की

@EliBendersky पूरी तरह से सहमत हैं। यह ऐसा है जैसे एसओ के पास एक सतत पहचान संकट है: जबकि यह स्पष्ट रूप से "नियमों" को फिट नहीं करता है (वैध उत्तरों की संख्या इसके लिए एक वसीयतनामा है), यह सिर्फ इतना है कि यह मूल्य जोड़ता है। सभी चीजें समान होने के बावजूद, मैं किसी ऐसे व्यक्ति के साथ काम करूंगा जिसने कोडिंग शैली पर कलात्मक और तर्कपूर्ण विचारों को विकसित किया है, भले ही उनके विचार मेरे से अलग हों।
Z4-tier

जवाबों:


748

आपको अपनी दूसरी सशर्त रेखा पर 4 रिक्त स्थान का उपयोग करने की आवश्यकता नहीं है। शायद उपयोग करें:

if (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

इसके अलावा, मत भूलो कि व्हाट्सएप अधिक लचीला है जितना आप सोच सकते हैं:

if (   
       cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something
if    (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

हालांकि दोनों काफी बदसूरत हैं।

शायद कोष्ठक खो देते हैं ( स्टाइल गाइड हालांकि इसे हतोत्साहित करता है)?

if cond1 == 'val1' and cond2 == 'val2' and \
   cond3 == 'val3' and cond4 == 'val4':
    do_something

यह कम से कम आपको कुछ भेदभाव देता है।

या और भी:

if cond1 == 'val1' and cond2 == 'val2' and \
                       cond3 == 'val3' and \
                       cond4 == 'val4':
    do_something

मुझे लगता है कि मुझे पसंद है:

if cond1 == 'val1' and \
   cond2 == 'val2' and \
   cond3 == 'val3' and \
   cond4 == 'val4':
    do_something

यहां स्टाइल गाइड है , जो (2010 से) कोष्ठक का उपयोग करने की सिफारिश करता है।


45
ध्यान दें कि PE / 8 द्वारा अनुगामी \ समाधान की अनुशंसा नहीं की जाती है। एक कारण यह है कि अगर किसी स्थान को गलती से जोड़ दिया जाता है तो यह आपके संपादक में नहीं दिखा सकता है, और कोड वाक्यविन्यास रूप से गलत हो जाता है।
एरिक ओ लेबिगॉट

14
यह गलत है, स्टाइल गाइड का कहना है, "कोष्ठक में अभिव्यक्तियों को लपेटकर लंबी लाइनों को कई लाइनों पर तोड़ा जा सकता है। इनका उपयोग लाइन निरंतरता के लिए बैकस्लैश का उपयोग करने के लिए प्राथमिकता में किया जाना चाहिए।" आप इसे यहाँ देख सकते हैं: python.org/dev/peps/pep-0008/#maximum-line-length
joshcartme

8
@joshcartme स्पष्ट रूप से बैकस्लैश को हतोत्साहित करने के लिए PEP hg.python.org/peps/rev/7a48207aaab6 पर बदल गया । मैं जवाब अपडेट कर दूंगा।
हार्ले होल्कोम्बे

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

3
PEP 8 अब andऔर ifसाथ ही ब्रेकिंग को हतोत्साहित करता है।
virtualxtc

124

मैंने पतित मामले में निम्नलिखित का सहारा लिया है, जहां यह केवल और या है।

if all( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

if any( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

यह कुछ पात्रों को हिलाता है और यह स्पष्ट करता है कि स्थिति के लिए कोई सूक्ष्मता नहीं है।


4
यह एक दिलचस्प दृष्टिकोण है। हालांकि लंबी स्थितियों के मुद्दे को संबोधित नहीं करता है
एली बेंडरस्की

20
यदि आप शॉर्टक्रिटिंग के बारे में परवाह नहीं करते हैं तो यह ठीक है।
कांस्टेंटिन

63
शॉर्टसर्किटिंग हमेशा उपवास के बारे में नहीं है। अच्छा कोडिंग अभ्यास नहीं करते हुए, आपके पास इस तरह का मौजूदा कोड हो सकता है if destroy_world and DestroyTheWorld() == world_is_destroyed: ...:। महान, अब आप बस दुर्घटना पर दुनिया को नष्ट कर दिया। आप कैसे कर सकते हैं?
आरोन

4
मुझे आश्चर्य है कि इसमें बहुत सारे उतार-चढ़ाव हैं। यह उत्तर पूरी तरह से मल्टी-लाइन सशर्त स्टाइल के बारे में मूल प्रश्न की उपेक्षा करता है ।
प्रेज़ेमेक डी

2
यह अभिव्यक्ति आलसी नहीं है। तो यह बराबर नहीं है अगर कुछ गार्डिंग की स्थिति का अनुसरण किया जा रहा है, जो संभवतः विफल हो सकता है।
यूजीन-उज्ज्वल

57

किसी को यहाँ ऊर्ध्वाधर व्हॉट्सएप का चैंपियन उपयोग करना है! :)

if (     cond1 == val1
     and cond2 == val2
     and cond3 == val3
   ):
    do_stuff()

इससे प्रत्येक स्थिति स्पष्ट रूप से दिखाई देती है। यह अधिक जटिल स्थितियों की क्लीनर अभिव्यक्ति की भी अनुमति देता है:

if (    cond1 == val1
     or 
        (     cond2_1 == val2_1
          and cond2_2 >= val2_2
          and cond2_3 != bad2_3
        )
   ):
    do_more_stuff()

हां, हम स्पष्टता के लिए लंबवत अचल संपत्ति का कारोबार कर रहे हैं। अच्छी तरह से इसके लायक IMO।


19
यह न तो सुंदर लगता है और न ही PEP8- संगत। PEP8 का कहना है कि बाइनरी ऑपरेटर (जैसे andऔर साथ ही or) के आसपास तोड़ने के लिए पसंदीदा जगह ऑपरेटर के बाद है, इससे पहले नहीं।
क्रिस मेड्रेला

7
@ChristopherMedrela क्या इसके पीछे का औचित्य बताता है? मुझे लगता है कि लॉजिक ऑपरेटर से पहले एक लाइन ब्रेक देना बहुत स्पष्ट है
नॉरिल टेम्पेस्ट

4
पहले ऑप्रेटर को डालना नोड की दुनिया में काफी आम है। तर्क यह है कि हम देखते हैं और बाईं ओर सामान को दायीं ओर सामान की तुलना में बहुत तेजी से पढ़ते हैं - कम से कम पश्चिमी संस्कृतियों में। जावास्क्रिप्ट में बहुत मान्य है, जहां एक भूला हुआ अल्पविराम मौन त्रुटियों का कारण बन सकता है।
टोमेक्वी

11
कृपया यह मत करो। न केवल यह है, PEP8बल्कि यह तर्क के संचालन को निर्धारित करने के लिए कठिन बना देता है कि आप किसके साथ पीछा कर रहे हैं। अगर यह कोड समीक्षा के माध्यम से मेरे डेस्क पर आया तो मैं इसे फैंक दूंगा।
उरदा

11
PEP8 के वर्तमान संस्करण के रूप में, बाइनरी ऑपरेटर से पहले या बाद में या तो तोड़ना स्वीकार्य माना जाता है , और ऑपरेटर को नए कोड के लिए बेहतर माना जाता है।
सोरेन ब्योर्नस्टैड

31

मैं इस शैली को पसंद करता हूं जब मेरे पास बहुत बड़ी अगर-हालत हो:

if (
    expr1
    and (expr2 or expr3)
    and hasattr(thingy1, '__eq__')
    or status=="HappyTimes"
):
    do_stuff()
else:
    do_other_stuff()

2
इंड्स रखने के लिए +1 जहां आप उनका ट्रैक रख सकते हैं। मैं अजगर को पसंद करता हूं और इसका भरपूर उपयोग करता हूं, लेकिन मुझे लगातार इंडेंट के लिए मजबूर होने से गुस्सा आ रहा है। मल्टी-लाइन अगर वास्तव में सौंदर्यशास्त्र को नष्ट कर देती है, तब भी जब अच्छी तरह से किया जाता है।
mightypile

4
ध्यान दें कि लाइन की शुरुआत में आपके andऔर orऑपरेटर होने से पीईपी 0008 का उल्लंघन होता है , जो बताता है कि "बाइनरी ऑपरेटर के चारों ओर तोड़ने के लिए पसंदीदा जगह ऑपरेटर के बाद है, इससे पहले नहीं।" । मुझे शरीर से अलग होने की स्थिति को अलग करने के लिए अपनी स्वयं की लाइन पर क्लोजिंग ब्रैकेट और कोलन होना पसंद है, हालांकि (और पीईपी-0008 अनुपालन के लिए लाइन के अंत में अपने बूलियन ऑपरेटरों को रखते हुए ऐसा करना पूरी तरह से संभव है)।
मार्क ऐमी

8
2016 के रूप में: For decades the recommended style was to break after binary operators. But this can hurt readability in two ways... In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth's style is suggested.(नुथ की शैली ऑपरेटर के साथ लाइन शुरू कर रही है)।
काउबर्ट

27

यहाँ मेरा बहुत ही व्यक्तिगत लेना है: लंबी शर्तें (मेरे विचार में) एक कोड गंध है जो बूलियन-रिटर्निंग फ़ंक्शन / विधि में रिफैक्टिंग करने का सुझाव देती है। उदाहरण के लिए:

def is_action__required(...):
    return (cond1 == 'val1' and cond2 == 'val2'
            and cond3 == 'val3' and cond4 == 'val4')

अब, अगर मुझे मल्टी-लाइन परिस्थितियों को अच्छा बनाने का एक तरीका मिल गया, तो मैं शायद खुद को उनके साथ होने वाली सामग्री ढूंढूंगा और रिफैक्टिंग को छोड़ दूंगा।

दूसरी ओर, उन्हें मेरे सौंदर्य बोध को बनाए रखने के लिए रिफैक्टिंग के लिए एक प्रोत्साहन के रूप में कार्य करता है।

इसलिए मेरा निष्कर्ष यह है कि कई लाइन की स्थिति बदसूरत दिखनी चाहिए और यह उनसे बचने के लिए एक प्रोत्साहन है।


23

यह इतना सुधार नहीं करता है लेकिन ...

allCondsAreOK = (cond1 == 'val1' and cond2 == 'val2' and
                 cond3 == 'val3' and cond4 == 'val4')

if allCondsAreOK:
   do_something

1
दिलचस्प विकल्प। लेकिन 2 अतिरिक्त पंक्तियाँ :-)
एली बेंडरस्की

Willnt वास्तव में एक पुनरावृत्त लूप में अच्छी तरह से काम करेगा, ऐसा कुछ करने वाले कार्यों के साथ काम नहीं करेगा ... और निष्पक्ष होने के लिए - बदसूरत
Mez

9
ब्रायन, मैं आंशिक रूप से असहमत हूं। गणना के मध्यवर्ती परिणामों के लिए चर का उपयोग करने से कोड को समझना आसान हो सकता है, और संकलित भाषा में कोई प्रदर्शन प्रभाव नहीं होगा। यह शायद अजगर में होता है, हालांकि मैं अजगर का उपयोग नहीं करता अगर पूर्णता वह महत्वपूर्ण थी।
मार्क बेकर

1
@MarkBaker मैं आपके लिखे हुए शब्दों से सहमत था, जब तक कि मैंने मार्टिन फाउलर्स को "रिफैक्टिंग" नहीं पढ़ा। वह एक उत्कृष्ट तर्क प्रदान करता है कि ऐसे मध्यवर्ती चर लाभ की तुलना में अधिक नुकसान पहुंचाते हैं। वे बाद के रीफैक्टरिंग को रोकते हैं। उनके बिना करना एक अधिक कार्यात्मक प्रोग्रामिंग शैली की ओर जाता है, जो खुद को रिफैक्टिंग करने के लिए अच्छी तरह से उधार देता है। इसने मुझे आश्चर्यचकित किया, लेकिन मेरा मानना ​​है कि वह सही है, और मेरे कोड से इस तरह के अनावश्यक मध्यवर्ती को खत्म करने के लिए स्ट्राइक के बाद से - भले ही वे एक से अधिक बार उपयोग किए जाते हैं।
जोनाथन हार्टले

2
अच्छा है, लेकिन ऊंट क्यों?! :)
लियोनिद श्वेचिकोव

19

मैं सुझाव देता हूं कि आगे बढ़ें and कीवर्ड को दूसरी पंक्ति में ले जाएं और चार के बजाय दो स्थानों के साथ शर्तों वाली सभी लाइनों को इंडेंट करें:

if (cond1 == 'val1' and cond2 == 'val2'
  and cond3 == 'val3' and cond4 == 'val4'):
    do_something

यह ठीक इसी प्रकार है कि मैं अपने कोड में इस समस्या को हल करता हूं। किसी कीवर्ड का लाइन में पहला शब्द होने से स्थिति बहुत अधिक पठनीय हो जाती है, और रिक्त स्थान की संख्या को कम करके स्थिति को कार्रवाई से अलग कर देती है।


9
मैंने ग्रिज़ या जिक्स्ट्रा दोनों में कहीं पढ़ा है कि तर्क ऑपरेटर को लाइन के सामने रखकर - अधिक दृश्यमान बनाने में मदद की। और मैं 90 के दशक से कर रहा हूं। और इससे मदद मिलती है।
एस.लूट

7
ध्यान दें कि स्टाइल गाइड लाइन के अंत में सशर्त लगाने की सलाह देता है।
हार्ले होल्कोम्बे

3
यह सच है, हालांकि मैं इस पर कभी भी इससे सहमत नहीं था। यह केवल एक मार्गदर्शक है, सब के बाद।
DzinX

8
PEP8 अब सशर्त को पंक्ति के अंत में रखने की अनुशंसा नहीं करता है
सोरेन ब्योर्नस्टैड

14

यह PEP 0008 (पायथन की आधिकारिक शैली गाइड) को उद्धृत करने के लायक लगता है , क्योंकि यह इस मुद्दे पर मामूली लंबाई पर टिप्पणी करता है:

जब if-statement का सशर्त भाग लंबे समय तक पर्याप्त होता है, तो यह आवश्यक है कि इसे कई लाइनों में लिखा जाए, यह ध्यान देने योग्य है कि दो वर्ण वाले कीवर्ड (अर्थात if) के संयोजन , साथ ही एक सिंगल स्पेस, और एक ओपनिंग कोष्ठक एक प्राकृतिक 4- बनाता है मल्टीलाइन सशर्त की बाद की लाइनों के लिए अंतरिक्ष इंडेंट। यह if-स्टैटमेंट के अंदर नेस्टेड कोड के इंडेंट सूट के साथ एक दृश्य संघर्ष पैदा कर सकता है , जो स्वाभाविक रूप से 4 रिक्त स्थान के लिए भी प्रेरित होगा। यह पीईपी इस बात पर कोई स्पष्ट स्थिति नहीं रखता है कि (या नहीं) if-स्टैटमेंट के अंदर नेस्टेड सूट से ऐसी सशर्त रेखाओं को कैसे अलग करना है। इस स्थिति में स्वीकार्य विकल्पों में शामिल हैं, लेकिन इन तक सीमित नहीं हैं:

# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

उपरोक्त उद्धरण में "सीमित नहीं" पर ध्यान दें; शैली गाइड में सुझाए गए दृष्टिकोणों के अलावा, इस प्रश्न के अन्य उत्तरों में सुझाए गए कुछ भी स्वीकार्य हैं।


PEP8 के लिए +1। यह स्वीकार किया जाना चाहिए , क्योंकि यह (व्यावहारिक रूप से बोल रहा है) आधिकारिक पायथन शैली गाइड है।
माइकल - जहां

2
यह भी जोर देने के लायक है कि, PEP8 स्पष्ट रूप से अपने रुख को बताता है क्योंकि यह PEP इस बात पर कोई स्पष्ट स्थिति नहीं लेता है कि (या क्या) अगर -स्टैटमेंट के अंदर नेस्टेड सूट से ऐसी सशर्त रेखाओं को अलग-अलग दिखाई दे। इस स्थिति में स्वीकार्य विकल्पों में शामिल हैं, लेकिन इन तक सीमित नहीं हैं: ... ( स्निप्ड ) इसलिए, बहस करना बंद करें, आप जिस चीज़ को पसंद करते हैं उसके साथ जाएं!
रायलूओ

7

यहाँ मैं क्या कर रहा हूँ, याद रखें कि "सभी" और "कोई भी" एक पुनरावृत्ति स्वीकार करता है, इसलिए मैं बस एक सूची में एक लंबी शर्त रखता हूं और "सभी" कार्य करता हूं।

condition = [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4']

if all(condition):
   do_something

4

मैं अपने पसंदीदा समाधान को देखकर आश्चर्यचकित हूं,

if (cond1 == 'val1' and cond2 == 'val2'
    and cond3 == 'val3' and cond4 == 'val4'):
    do_something

चूंकि andएक कीवर्ड है, यह मेरे संपादक द्वारा हाइलाइट किया गया है, और इसके नीचे do_something से पर्याप्त रूप से अलग दिखता है।


लेकिन निरंतरता रेखा अभी भी अगली तार्किक रेखा से अलग नहीं है ...
क्रिस मेड्रेला

1
ध्यान दें कि यह पीईपी 0008 उल्लंघन है ( "बाइनरी ऑपरेटर के चारों ओर तोड़ने के लिए पसंदीदा स्थान ऑपरेटर के बाद है, इससे पहले नहीं" )। चाहे आप देखभाल करें, बेशक, आप पर निर्भर है।
मार्क अमेरी

1
संयोग से, यह अब मेरा पसंदीदा समाधान नहीं है। ;)
मारीस गेदमिनस

4

@Krawyoti ने जो कहा, उसे जोड़ते हुए ... लंबी स्थितियों की गंध आती है क्योंकि उन्हें पढ़ना मुश्किल है और समझना मुश्किल है। किसी फंक्शन या वेरिएबल का इस्तेमाल करने से कोड क्लियर हो जाता है। पायथन में, मैं ऊर्ध्वाधर स्थान का उपयोग करना पसंद करता हूं, लघुकोष्ठक संलग्न करता हूं, और प्रत्येक पंक्ति की शुरुआत में तार्किक ऑपरेटरों को रखता हूं ताकि अभिव्यक्तियां "फ्लोटिंग" की तरह न दिखें।

conditions_met = (
    cond1 == 'val1' 
    and cond2 == 'val2' 
    and cond3 == 'val3' 
    and cond4 == 'val4'
    )
if conditions_met:
    do_something

यदि परिस्थितियों को एक से अधिक बार मूल्यांकन करने की आवश्यकता होती है, जैसा कि whileलूप में है, तो स्थानीय फ़ंक्शन का उपयोग करना सबसे अच्छा है।


1
इसके अतिरिक्त आप एक अतिरिक्त चर बनाने के विरोध में अपने असली झूठ को वापस करने के लिए एक फ़ंक्शन या लैम्ब्डा की घोषणा कर सकते हैं।
टेकड्रैगन

@Techdragon अगर स्थितियां कहीं और होनी हैं, तो उन्हें लैम्ब्डा ब्लॉक में डालने के लिए लैम्ब्डा ब्लॉक को नाम देना होगा, ताकि बाद में अगर वह इस स्थिति में संदर्भित हो सके। यदि एक मेमने का नाम होने जा रहा है, तो यह एक नियमित कार्य क्यों है? मैं व्यक्तिगत रूप से इस तरह की बूलियन अभिव्यक्ति को कम करता हूं।
श्री कादिमीसेट्टी

मैं सहमत हूं, यही वजह है कि मैं सामान्य रूप से सुधार और पठनीयता में सुधार के लिए ज्यादातर मामलों में एक फ़ंक्शन का उपयोग करता हूं, जब प्रोग्राम नियंत्रण प्रवाह को समझने के लिए स्किमिंग होती है। मैं यह सुनिश्चित करने के लिए लैंबडा का उल्लेख करता हूं कि 'छोटे' विकल्प भी मौजूद है जब लोग विशेष रूप से अंतरिक्ष के प्रति जागरूक होते हैं।
टेकड्रागन

4

व्यक्तिगत रूप से, मुझे लंबे इफ-स्टेटमेंट्स से मतलब जोड़ना पसंद है। मुझे एक उपयुक्त उदाहरण खोजने के लिए कोड के माध्यम से खोजना होगा, लेकिन यहां पहला उदाहरण जो मन में आता है: मान लीजिए कि मैं कुछ विचित्र तर्क में भाग लेता हूं जहां मैं कई चर के आधार पर एक निश्चित पृष्ठ प्रदर्शित करना चाहता हूं।

अंग्रेजी: "यदि लॉग-इन उपयोगकर्ता एक प्रशासक शिक्षक नहीं है, लेकिन सिर्फ एक नियमित शिक्षक है, और खुद एक छात्र नहीं है ..."

if not user.isAdmin() and user.isTeacher() and not user.isStudent():
    doSomething()

यकीन है कि यह ठीक लग सकता है, लेकिन अगर बयान बहुत काम आते हैं तो उन्हें पढ़ना। कैसे के बारे में हम तर्क है कि समझ में आता है लेबल करने के लिए प्रदान करते हैं। "लेबल" वास्तव में परिवर्तनशील नाम है:

displayTeacherPanel = not user.isAdmin() and user.isTeacher() and not user.isStudent()
if displayTeacherPanel:
    showTeacherPanel()

यह मूर्खतापूर्ण लग सकता है, लेकिन आपके पास अभी तक एक और शर्त हो सकती है जहां आप केवल एक और आइटम प्रदर्शित करना चाहते हैं यदि, और केवल अगर, आप शिक्षक पैनल प्रदर्शित कर रहे हैं या यदि उपयोगकर्ता डिफ़ॉल्ट रूप से उस अन्य विशिष्ट पैनल तक पहुंच रखता है:

if displayTeacherPanel or user.canSeeSpecialPanel():
    showSpecialPanel()

अपने तर्क को संग्रहीत और लेबल करने के लिए चर का उपयोग किए बिना उपरोक्त स्थिति को लिखने का प्रयास करें, और न केवल आप बहुत ही गन्दा, कठिन-से-पढ़ा हुआ तार्किक कथन समाप्त करते हैं, बल्कि आपने खुद को भी दोहराया है। हालांकि, इसके कुछ अपवाद हैं, याद रखें: डोंट रिपिट योरसेल्फ (DRY)।


3

"सभी" और "कोई भी" एक ही प्रकार के मामले की कई स्थितियों के लिए अच्छे हैं। लेकिन वे हमेशा सभी स्थितियों का मूल्यांकन करते हैं। जैसा कि इस उदाहरण में दिखाया गया है:

def c1():
    print " Executed c1"
    return False
def c2():
    print " Executed c2"
    return False


print "simple and (aborts early!)"
if c1() and c2():
    pass

print

print "all (executes all :( )"
if all((c1(),c2())):
    pass

print

5
गलत! वे केवल इसलिए करते हैं कि आप करते हैं। [सी 1, सी 2] में एफ के लिए सभी (एफ) की कोशिश करें।
हबनबीत

2
मुझे लगता है कि वह केवल एक उदाहरण के रूप में कार्यों का उपयोग कर रहा था, क्योंकि वह आसानी से उन्हें कुछ प्रिंट कर सकता है। यदि हम all()तब तक एक सूची में दिए गए मनमाने भावों की एक श्रृंखला पर विचार कर रहे हैं , जब तक कि आप उन्हें एक-एक लंबोदर में लपेटने और अपनी f()चाल का उपयोग करने के लिए नहीं जा रहे हैं, वे सभी का मूल्यांकन करने जा रहे हैं। दूसरे शब्दों में, हारून: मुझे लगता है कि एंडर्स सामान्य परिस्थितियों में एक विशिष्ट उदाहरण के रूप में कॉलबल्स का उपयोग करने के बारे में बात करने की कोशिश कर रहा था; लेकिन आपका आनन्द केवल कार्यों के लिए लागू होता है।
ब्रैंडन रोड्स

3

(मैंने पहचानने वालों को हल्के ढंग से संशोधित किया है क्योंकि निश्चित-चौड़ाई के नाम वास्तविक कोड के प्रतिनिधि नहीं हैं - कम से कम वास्तविक कोड नहीं है जो मैं सामना करता हूं - और एक उदाहरण की पठनीयता पर विश्वास करूंगा।)

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4"):
    do_something

यह "और" और "या" के लिए अच्छी तरह से काम करता है (यह महत्वपूर्ण है कि वे पहली पंक्ति पर हैं), लेकिन अन्य लंबी स्थितियों के लिए बहुत कम। सौभाग्य से, पहले वाला अधिक सामान्य मामला प्रतीत होता है जबकि बाद वाले अक्सर एक अस्थायी चर के साथ आसानी से फिर से लिखे जाते हैं। (यह आमतौर पर कठिन नहीं है, लेकिन पुनर्लेखन के दौरान "और" / "या" के लघु परिचलन को संरक्षित करना मुश्किल या बहुत कम स्पष्ट / पठनीय हो सकता है।)

चूँकि मुझे C ++ के बारे में आपके ब्लॉग पोस्ट से यह प्रश्न मिला , इसलिए मैं इसमें शामिल करता हूँ कि मेरी C ++ शैली समान है:

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4") {
    do_something
}

3

सादा और सरल, pep8 चेक भी पास करता है:

if (
    cond1 and
    cond2
):
    print("Hello World!")

हाल के दिनों में मैं उन कार्यों allऔर anyकार्यों को प्राथमिकता दे रहा हूं, क्योंकि मैं शायद ही कभी मिश्रण करता हूं और या तुलना करता है कि यह अच्छी तरह से काम करता है, और जनरेटर को समझने के साथ फेलिंग अर्ली का अतिरिक्त लाभ है:

if all([
    cond1,
    cond2,
]):
    print("Hello World!")

बस एक भी चलने में पारित याद है! एन-दलीलों में पास करना सही नहीं है।

नोट: anyकई orतुलनाओं allकी तरह है, कई andतुलनाओं की तरह है ।


यह उदाहरण के लिए, जनरेटर की समझ के साथ अच्छी तरह से जोड़ता है:

# Check if every string in a list contains a substring:
my_list = [
    'a substring is like a string', 
    'another substring'
]

if all('substring' in item for item in my_list):
   print("Hello World!")

# or

if all(
    'substring' in item
    for item in my_list
):
    print("Hello World!")

अधिक पर: जनरेटर की समझ


1
मुझे यह भी इंगित करना चाहिए कि पाइलिंट का स्टॉक कॉन्फ़िगरेशन एक में लाइन निरंतरता पर एक प्रवेश इंडेंट चाहता है; जिसने मुझे इस योजना का उपयोग करने से मना कर दिया है।
थोरसुमोनर

2

क्या होगा यदि हम केवल स्थिति और शरीर के बीच एक अतिरिक्त रिक्त रेखा सम्मिलित करते हैं और शेष विहित तरीके से करते हैं?

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):

    do_something

ps मैं हमेशा टैब का उपयोग करता हूं, रिक्त स्थान का नहीं; मैं ठीक नहीं कर सकता ...


3
यह बहुत भ्रामक होगा, खासकर जब सशर्त का शरीर लंबा होता है, मुझे लगता है।
एली बेंडरस्की

मैं एली के साथ सहमत हूं, यहां का एनकैप्सुलेशन और इंडेंटेशन लंबी लाइनों के लिए भ्रमित है। इसके अलावा, नया नियम यह है कि बयान andऔर orकथन अगली पंक्ति पर शुरू होने चाहिए
virtualxtc

2

मैं आमतौर पर क्या करता हूं:

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something

इस तरह से बंद कंस और बृहदान्त्र नेत्रहीन हमारी स्थिति के अंत को चिह्नित करते हैं।


1
लगभग सही; PEP 8 अब andया से पहले तोड़ने की सलाह देता है or
virtualxtc

2

सभी स्टेटमेंट्स जो कि स्टेटमेंट के लिए मल्टी-कंडीशंस प्रदान करते हैं, केवल प्रस्तुत समस्या के रूप में बदसूरत है। आप एक ही काम करके इस समस्या का समाधान नहीं करते हैं।

यहां तक ​​कि पीईपी 0008 का उत्तर भी प्रतिकारक है।

यहाँ कहीं अधिक पठनीय दृष्टिकोण है

condition = random.randint(0, 100) # to demonstrate
anti_conditions = [42, 67, 12]
if condition not in anti_conditions:
    pass

मुझे मेरे शब्द खाने के लिए चाहते हैं? मुझे समझाएं कि आपको मल्टी-कंडीशंस की आवश्यकता है और मैं सचमुच इसे प्रिंट करूंगा और इसे आपके मनोरंजन के लिए खाऊंगा।


यह वास्तव में बहु-सशर्त करने का एक बहुत साफ तरीका है :) यह नहीं जानते कि इसके पास अधिक वोट क्यों नहीं हैं :), क्या कोई चेतावनी है?
dim_user

@SaulCruz वास्तव में न केवल स्थिति चर को दोहराए जाने की आवश्यकता नहीं है, आपको प्रत्येक मूल्य की जाँच के कई डुप्लिकेट पर भी सहेजने की ज़रूरत नहीं है, यह केवल एक सरणी में केवल मान डालता है और इंजन को इसे (अनुकूलित) काम करने देता है आपके लिए स्थिति की जाँच करना
Stoff

@Stoff मेरी टिप्पणी को हटाने के लिए धन्यवाद। मैं यह बताना चाहता था कि आपका दृष्टिकोण ओपी के प्रश्न का उत्तर नहीं देता है। आपके द्वारा प्रदान किया गया कोड प्रश्न में कोड पर लागू नहीं किया जा सकता है। यदि आप अन्यथा सोचते हैं, तो आपको अपनी बात को साबित करने के लिए अपने दृष्टिकोण से ओपी के सुधार को जोड़ना चाहिए।
ज्येकोमन

यह स्वीकृत जवाब नहीं है, हालांकि यह स्पष्ट रूप से एक वैकल्पिक दृष्टिकोण है (अन्य सहमत हैं)। एसओ ने वैकल्पिक उत्तरों को प्रोत्साहित किया ताकि तर्क क्या हो? अपने स्वयं के प्रश्न में स्पष्ट रहें, शायद अपने स्वयं के प्रश्न को खोलने पर विचार करें यदि आपको उचित ध्यान देने की आवश्यकता है। Ps मैं एक SO मॉड नहीं हूं, मैं टिप्पणियों को नहीं हटा सकता हूं
Stoff

2

मुझे लगता है कि @ ज़कंडा का समाधान एक मामूली मोड़ के साथ अच्छा होगा। यदि आपकी अपनी सूची में आपकी शर्तें और मूल्य हैं, तो आप तुलना करने के लिए एक सूची समझ का उपयोग कर सकते हैं, जो स्थिति / मूल्य जोड़े को जोड़ने के लिए चीजों को थोड़ा अधिक सामान्य बना देगा।

conditions = [1, 2, 3, 4]
values = [1, 2, 3, 4]
if all([c==v for c, v in zip(conditions, values)]):
    # do something

अगर मैं इस तरह एक बयान को हार्ड-कोड करना चाहता था, तो मैं इसे इस तरह से लिखूंगा

if (condition1==value1) and (condition2==value2) and \
   (condition3==value3) and (condition4==value4):

और बस एक iandऑपरेटर के साथ एक और समाधान बाहर फेंकने के लिए :

proceed = True
for c, v in zip(conditions, values):
    proceed &= c==v

if proceed:
    # do something

1
सिर्फ मनोरंजन के लिए all(map(eq, have, expected)):। (साथ from operator import eq)
गेब्रियल गार्सिया

1

संपूर्णता के लिए कुछ अन्य यादृच्छिक विचार। यदि वे आपके लिए काम करते हैं, तो उनका उपयोग करें। अन्यथा, आप शायद कुछ और कोशिश कर रहे हैं।

आप इसे एक शब्दकोश के साथ भी कर सकते हैं:

>>> x = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> y = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> x == y
True

यह विकल्प अधिक जटिल है, लेकिन आपको यह उपयोगी भी लग सकता है:

class Klass(object):
    def __init__(self, some_vars):
        #initialize conditions here
    def __nonzero__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
                self.cond3 == 'val3' and self.cond4 == 'val4')

foo = Klass()
if foo:
    print "foo is true!"
else:
    print "foo is false!"

अगर आप के लिए यह काम करता है, लेकिन यह विचार करने के लिए एक और विकल्प है। यहाँ एक और तरीका है:

class Klass(object):
    def __init__(self):
        #initialize conditions here
    def __eq__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
               self.cond3 == 'val3' and self.cond4 == 'val4')

x = Klass(some_values)
y = Klass(some_other_values)
if x == y:
    print 'x == y'
else:
    print 'x!=y'

पिछले दो मैंने परीक्षण नहीं किया है, लेकिन अवधारणाएं आपको पाने के लिए पर्याप्त होनी चाहिए यदि आप चाहते हैं कि आप इसके साथ जाना चाहते हैं।

(और रिकॉर्ड के लिए, अगर यह सिर्फ एक बार की बात है, तो आप शायद आपके द्वारा पहले प्रस्तुत की गई विधि का उपयोग करने से बेहतर हैं। यदि आप बहुत से स्थानों पर तुलना कर रहे हैं, तो ये विधियाँ पठनीयता को बढ़ाने के लिए पर्याप्त हो सकती हैं आप इस तथ्य के बारे में इतना बुरा महसूस नहीं करते हैं कि वे एक प्रकार का हैकी हैं। "


1

मैं ऐसा करने के लिए एक अच्छा तरीका खोजने के लिए संघर्ष कर रहा हूं, इसलिए मैं सिर्फ एक विचार (चांदी की गोली नहीं, क्योंकि यह मुख्य रूप से स्वाद का मामला है) के साथ आया था।

if bool(condition1 and
        condition2 and
        ...
        conditionN):
    foo()
    bar()

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

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

if (((foo and
      bar and
      frob and
      ninja_bear))):
    do_stuff()

मुझे यह पसंद है क्योंकि जब आप इसे देखते हैं, तो आपके सिर में एक घंटी तुरंत बजती है "अरे, यहाँ एक जटिल चीज चल रही है!" । हां, मुझे पता है कि कोष्ठक पठनीयता में मदद नहीं करते हैं, लेकिन इन स्थितियों को शायद ही कभी पर्याप्त रूप से प्रकट होना चाहिए, और जब वे दिखाई देते हैं, तो आपको वैसे भी उन्हें रोकना और पढ़ना होगा (क्योंकि वे जटिल हैं )।

वैसे भी, दो और प्रस्ताव जो मैंने यहां नहीं देखे हैं। आशा है कि यह किसी की मदद करता है :)


1

आप इसे दो लाइनों में विभाजित कर सकते हैं

total = cond1 == 'val' and cond2 == 'val2' and cond3 == 'val3' and cond4 == val4
if total:
    do_something()

या यहां तक ​​कि एक समय में एक शर्त पर जोड़ें। इस तरह, कम से कम यह अव्यवस्था को इससे अलग करता है if


1

मुझे पता है कि यह धागा पुराना है, लेकिन मेरे पास कुछ पायथन 2.7 कोड है और PyCharm (4.5) अभी भी इस मामले के बारे में शिकायत करता है:

if foo is not None:
    if (cond1 == 'val1' and cond2 == 'val2' and
        cond3 == 'val3' and cond4 == 'val4'):
            # some comment about do_something
            do_something

PEP8 चेतावनी के साथ "अगली तार्किक रेखा के समान इंडेंट वाली नेत्रहीन इंडेंटेड लाइन" के साथ, वास्तविक कोड पूरी तरह से ठीक है? यह "अति-इंडेंटिंग नहीं है?"

... कई बार मैं इच्छा करता हूं कि पायथन को थोड़ी सी गोली लगे और बस घुंघराले ब्रेस के साथ चले। मुझे आश्चर्य है कि आकस्मिक रूप से गलत इंडेंटेशन के कारण पिछले कुछ वर्षों में कितने कीड़े हो गए हैं ...


0

अपनी शर्तों को सूची में पैक करें, फिर smth करें। पसंद:

if False not in Conditions:
    do_something

0

मुझे लगता है कि जब मेरे पास लंबी शर्तें होती हैं, तो मेरे पास अक्सर एक शॉर्ट कोड बॉडी होती है। उस मामले में, मैं सिर्फ शरीर को डबल-इंडेंट करता हूं, इस प्रकार:

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):
        do_something

1
@qarma, क्या आप विस्तार करना चाहेंगे? यह निश्चित रूप से लाइन-निरंतरता वर्णों का उपयोग करने से बेहतर है, जो पीईपी 8 के खिलाफ सुझाए गए हैं
xorsyst

यह वास्तव में लाइन निरंतरता के लिए एक वैध मामला है। IMPO कोष्ठक एक ट्यूल या एक फ़ंक्शन कॉल को दर्शाता है। ओपी का उपयोग बहुत ही सी-लाइक है, जब भी संभव हो मैं अजगर सिंटैक्स पसंद करता हूं। मैं स्वीकार करता हूं कि हालांकि सार्वभौमिक रूप से इष्ट नहीं है।
दिमा तिस्नेक

0
  if cond1 == 'val1' and \
     cond2 == 'val2' and \
     cond3 == 'val3' and \
     cond4 == 'val4':
      do_something

या यदि यह स्पष्ट है:

  if cond1 == 'val1'\
     and cond2 == 'val2'\
     and cond3 == 'val3'\
     and cond4 == 'val4':
      do_something

कोई कारण नहीं है कि इस मामले में इंडेंट 4 का एक होना चाहिए, उदाहरण के लिए "ओपनिंग सीमांकक के साथ संरेखित" देखें:

http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation


Google की मार्गदर्शिका एक जटिल स्थिति का उदाहरण भी देती है , जो ओपी के अनुसार "ऐसा करने का सबसे स्पष्ट तरीका" है। हालांकि गाइड स्पष्ट रूप से लंबे "अगर" इस ​​तरह से प्रारूपण की वकालत नहीं करता है।
एंटोन स्ट्रोगोनॉफ

0

यहाँ एक और दृष्टिकोण है:

cond_list = ['cond1 == "val1"','cond2=="val2"','cond3=="val3"','cond4=="val4"']
if all([eval(i) for i in cond_list]):
 do something

यह भी आसानी से सूची में एक और शर्त जोड़कर अगर बयान को बदलने के बिना एक और शर्त को आसानी से जोड़ना आसान बनाता है:

cond_list.append('cond5=="val5"')


0

अगर हमारी if & a अन्य स्थिति को इसके अंदर कई स्टेटमेंट निष्पादित करने पड़ते हैं तो हम नीचे की तरह लिख सकते हैं। हर जब हमारे पास है तो उसके अंदर एक कथन के साथ उदाहरण।

धन्यवाद यह मेरे लिए काम करता है।

#!/usr/bin/python
import sys
numberOfArgument =len(sys.argv)
weblogic_username =''
weblogic_password = ''
weblogic_admin_server_host =''
weblogic_admin_server_port =''


if numberOfArgument == 5:
        weblogic_username = sys.argv[1]
        weblogic_password = sys.argv[2]
        weblogic_admin_server_host =sys.argv[3]
        weblogic_admin_server_port=sys.argv[4]
elif numberOfArgument <5:
        print " weblogic UserName, weblogic Password and weblogic host details are Mandatory like, defalutUser, passwordForDefaultUser, t3s://server.domainname:7001 ."
        weblogic_username = raw_input("Enter Weblogic user Name")
        weblogic_password = raw_input('Enter Weblogic user Password')
        weblogic_admin_server_host = raw_input('Enter Weblogic admin host ')
        weblogic_admin_server_port = raw_input('Enter Weblogic admin port')
#enfelif
#endIf

0

मेरी अभद्रता को क्षमा करें, लेकिन ऐसा होता है कि मैं यहाँ #Python का जानकार नहीं हूँ, जैसा कि आप में से किसी के यहाँ है, लेकिन ऐसा होता है कि मुझे 3D BIM मॉडलिंग में अपनी वस्तुओं की स्क्रिप्टिंग करते समय कुछ ऐसा ही मिला है, इसलिए मैं आपके एल्गोरिथ्म को अनुकूलित करूँगा। अजगर की।

मुझे यहां जो समस्या है, वह दो तरफा है:

  1. मान किसी के लिए विदेशी लगते हैं जो स्क्रिप्ट को समझने की कोशिश कर सकता है।
  2. कोड मान उच्च लागत पर आएगा, यदि उन मानों को बदल दिया जाता है (सबसे संभावित), या यदि नई शर्तें जोड़ी जानी चाहिए (टूटी स्कीमा)

इन सभी समस्याओं को बायपास करने के लिए, आपकी स्क्रिप्ट को इस तरह जाना चाहिए

param_Val01 = Value 01   #give a meaningful name for param_Val(i) preferable an integer
param_Val02 = Value 02
param_Val03 = Value 03
param_Val04 = Value 04   # and ... etc

conditions = 0           # this is a value placeholder

########
Add script that if true will make:

conditions = conditions + param_Val01   #value of placeholder is updated
########

### repeat as needed


if conditions = param_Val01 + param_Val02 + param_Val03 + param_Val04:
    do something

इस विधि के पेशेवरों:

  1. स्क्रिप्ट पठनीय है।

  2. स्क्रिप्ट को आसान बनाए रखा जा सकता है।

  3. स्थितियाँ मानों के योग के लिए 1 तुलनात्मक ऑपरेशन है जो वांछित स्थितियों का प्रतिनिधित्व करता है।
  4. बहुस्तरीय परिस्थितियों के लिए कोई ज़रूरत नहीं है

आशा है कि यह आप सभी की मदद करेंगे

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.