سؤال

في بعض الأحيان أقوم بكسر الشروط الطويلة ifق على عدة أسطر.الطريقة الأكثر وضوحًا للقيام بذلك هي:

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

ليست جذابة للغاية من الناحية البصرية، لأن الحركة تمتزج مع الظروف.ومع ذلك، فهذه هي الطريقة الطبيعية لاستخدام مسافة بادئة صحيحة لـ Python مكونة من 4 مسافات.

في الوقت الحالي أستخدم:

  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

وأيضا، لا ننسى المسافات أكثر مرونة مما تظن:

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) توصي باستخدام الأقواس.

نصائح أخرى

ولقد لجأت إلى ما يلي في حالة منحطة حيث انها ببساطة AND أو OR ل.

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

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

وحلق عدد قليل من الشخصيات، ويجعل من الواضح أنه لا يوجد دقة لهذه الحالة.

شخص أن استخدام بطل المسافات الرأسية هنا! :)

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.

وهنا بلدي يأخذ شخصي جدا: شروط الشراء هي (في رأيي) رائحة التعليمات البرمجية التي يقترح إعادة الهيكلية إلى وظيفة / طريقة العائدين منطقية. على سبيل المثال:

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

والآن، إذا وجدت وسيلة لجعل الظروف متعدد الخطوط تبدو جيدة، وأنا ربما أجد نفسي محتوى مع وجود لهم والقفز على إعادة بيع ديون.

من ناحية أخرى، وجود لهم التشويش على بلدي الجمالية أعمال الشعور كحافز لإعادة الهيكلية.

واستنتاجي، لذلك، هو أن الظروف خط متعددة يجب أن تبدو قبيحة وهذا هو حافز لتفاديها.

وهذا لا يحسن كثيرا ولكن ...

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

if allCondsAreOK:
   do_something

وأنا أفضل هذا الأسلوب عندما يكون لدي حالة إذا الكبيرة بشكل رهيب:

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

وأقترح تحريك الكلمة and إلى السطر الثاني والطعج عن الأسطر التي تحتوي على الشروط مع مسافتين بدلا من أربعة:

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

وهذا هو بالضبط كيف يمكنني حل هذه المشكلة في قانون بلدي. وجود الكلمة والكلمة الأولى في السطر يجعل حالة الكثير أكثر قابلية للقراءة، والحد من عدد المسافات أبعد يميز حالة من العمل.

ويبدو يستحق نقلا عن PEP 0008 (ودليل أسلوب بايثون الرسمي)، لأنه يعلق على هذه المسألة في طول متواضع:

<اقتباس فقرة>   

عند الجزء المشروط من -بيان if طويلة بما فيه الكفاية تتطلب أن تكون مكتوبة عبر خطوط متعددة، ومن الجدير بالذكر أن الجمع بين الكلمة اثنين من حرف (أي if)، بالإضافة إلى مسافة واحدة، بالإضافة إلى قوس فتح يخلق مسافة بادئة 4 مساحة طبيعية للخطوط لاحقة من متعدد مشروطة. هذا يمكن أن يؤدي إلى الصراع البصري مع جناح بادئة من التعليمات البرمجية المتداخلة داخل -بيان if، الذي من شأنه أيضا أن من الطبيعي أن يكون بادئة إلى 4 مسافات. هذا PEP يأخذ أي موقف واضح حول كيفية (أم) لزيادة بصريا تميز هذه خطوط مشروط من مجموعة متداخلة داخل -بيان 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()

لاحظ "لا تقتصر على" في الاقتباس أعلاه؛ إلى جانب النهج المقترحة في دليل الاسلوب، وبعض من تلك المقترحة في إجابات أخرى على هذا السؤال مقبولة جدا.

إليك ما أقوم به، وتذكر أن "كل" و "أي" يقبل iterable، لذلك أنا فقط وضعت شرطا طويلة في قائمة والسماح "عن" قيام بهذا العمل.

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

if all(condition):
   do_something

وأنا مندهش لا أرى الحل المفضل،

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

ومنذ and هو الكلمة، ويحصل على الضوء من قبل بلدي المحرر، وتبدو مختلفة بما فيه الكفاية من do_something تحتها.

وشخصيا، أود أن أضيف معنى ل-البيانات إذا طويلة. كنت أود أن يكون للبحث عن طريق كود للعثور على سبيل المثال المناسب، ولكن هنا في المثال الأول الذي يتبادر إلى الذهن: دعنا نقول يحدث لي أن واجهت بعض المنطق ملتوي حيث أريد لعرض صفحة معينة اعتمادا على متغيرات كثيرة

والإنجليزية: "إذا كان المستخدم بتسجيل الدخول في غير NOT مدرسا المسؤول، ولكن هو مجرد معلم منتظم، وليس الطلاب أنفسهم ..."

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)

و"جميع" و "أي" لطيفة لظروف عديدة من حالة نوع نفسها. لكنها دائما بتقييم جميع الظروف. كما هو موضح في هذا المثال:

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

و(لقد تعديل طفيفة معرفات كأسماء ذات العرض الثابت لا تمثل كود الحقيقي - على الأقل ليس رمز حقيقي من أن واجهت - وسوف تكذب على سبيل المثال في القراءة)

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

وهذا يعمل بشكل جيد ل"و" و "أو" (من المهم انهم لأول مرة على السطر الثاني)، ولكن أقل بكثير من ذلك لظروف طويلة أخرى. لحسن الحظ، يبدو السابق أن هذا هو الحال أكثر شيوعا في حين أن الأخيرة غالبا ما يتم كتابته بسهولة مع متغير مؤقت. (انها عادة ليس من الصعب، ولكن قد يكون من الصعب أو أقل وضوحا / قراءتها للحفاظ على في الدائرة القصيرة "و" / "أو" عند إعادة كتابة).

وبما أنني وجدت هذا السؤال من <لأ href = "http://eli.thegreenplace.net/2011/01/14/how-python-affected-my-cc-brace-style/" يختلط = "نوفولو" > الخاص بك بلوق وظيفة حول C ++ ، سوف تتضمن أن بلدي C ++ أسلوب مطابق:

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

وإضافة إلى ما قالهkrawyoti ... الظروف الطويلة رائحة لأنها صعبة القراءة ويصعب فهمه. باستخدام وظيفة أو متغير يجعل رمز أكثر وضوحا. في بيثون، أنا أفضل أن استخدام الفضاء الرأسي، وأرفق قوسين، ووضع العوامل المنطقية في بداية كل سطر حتى التعبيرات لا تبدو وكأنها "عائم".

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

إذا تحتاج الشروط الواجب تقييمها أكثر من مرة واحدة، كما هو الحال في حلقة while، ثم باستخدام وظيفة المحلية هو أفضل.

وسهل وبسيط، كما يمر الشيكات pep8:

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

في الآونة الأخيرة لقد كنت فضلت وظائف all وany، لأنني نادرا ما خلط ووأو مقارنات هذا يعمل بشكل جيد، ولها ميزة إضافية تتمثل في الفشل المبكر مع مولدات الفهم:

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

وتذكر فقط أن تمر في iterable احد! يمر في N-حجج غير صحيحة.

ملحوظة: any ومثل العديد من المقارنات or، all مثل العديد من المقارنات and

.

وهذا يجمع بين لطيف مع comprehensions مولد، على سبيل المثال:

# 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!")

والمزيد على مولد الفهم

وماذا لو أننا فقط إدراج سطر فارغ إضافية بين حالة والجسم وتفعل بقية في الطريق الكنسي؟

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

    do_something

وp.s. أنا دائما استخدام علامات التبويب، وليس مساحات. لا أستطيع صقل ...

وعلى بعد بضعة أفكار عشوائية أخرى من أجل اكتمال الصورة. إذا كانت تعمل من أجلك، واستخدامها. خلاف ذلك، وربما كنت أفضل حالا في محاولة شيء آخر.

ويمكنك أيضا أن تفعل هذا مع القاموس:

>>> 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'

والأخيرين أنا لم تختبر، ولكن ينبغي المفاهيم تكون كافية لتحصل على الذهاب اذا كان هذا ما تريد أن تذهب معه.

(وللسجل، وإذا كان هذا هو مجرد شيء مرة واحدة، وربما كنت أفضل قبالة باستخدام الطريقة التي قدمت في البداية، وإذا كنت تفعل المقارنة في الكثير من الأماكن، قد تكون هذه الأساليب تعزيز القراءة ما يكفي لجعل لكم لا يشعرون سيئة للغاية عن حقيقة أنها هي نوع من hacky).

وماذا أفعل عادة هو:

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

وبهذه الطريقة قوس الإغلاق والقولون بصريا بمناسبة نهاية حالتنا.

ولقد تم تكافح من أجل إيجاد طريقة لائقة للقيام بذلك أيضا، لذلك جئت للتو مع فكرة (وليس عصا سحرية، لأن هذا هو أساسا مسألة ذوق).

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

وأجد بعض المزايا في هذا الحل بالمقارنة مع الآخرين رأيت، وهي تحصل بالضبط اضافي 4 فضاءات المسافة البادئة (منطقي)، مما يتيح لجميع الشروط ليصطف عموديا، وجسم بيان إذا يمكن يتم تحريكها في (إيش) طريقة واضحة. هذا أيضا يحافظ على فوائد تقييم ماس كهربائى من العوامل المنطقية، ولكن بالطبع يضيف مقدار الحمل استدعاء دالة الذي لا يفعل شيئا في الأساس. هل يمكن القول (صحيحا) أن أي وظيفة عودته حجتها يمكن استخدامها هنا بدلا من منطقي، ولكن كما قلت، انها مجرد فكرة وانها في نهاية المطاف مسألة ذوق.

ومضحك بما فيه الكفاية، وأنا أكتب هذا والتفكير في "مشكلة"، خطرت لي <م> بعد آخر فكرة، الذي يزيل الزائد من استدعاء دالة. لماذا لا تشير إلى أننا على وشك الدخول في حالة معقدة باستخدام أزواج إضافية من الأقواس؟ أقول، 2 أكثر، لإعطاء لطيفة المسافة البادئة 2 مساحة الشروط الفرعية بالنسبة للجسم اذا البيان. مثال:

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

والنوع الأول من مثل هذا لأنه عندما ننظر في الأمر، جرس يرن فورا، في رأسك قائلا <م> "مهلا، هناك شيء معقد يحدث هنا!" . نعم، وأنا أعلم أن الأقواس لا تساعد على القراءة، ولكن يجب أن تظهر هذه الشروط نادرا بما فيه الكفاية، وعندما تفعل ذلك تظهر، وأنت تسير لدينا لوقف وقراءتها carefuly على أي حال (لأنهم على مجمع ).

وعلى أي حال، مجرد اثنين من أكثر المقترحات التي أنا لم أر هنا. آمل أن يساعد هذا شخص:)

هل يمكن تقسيمه إلى سطرين

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

وأو حتى إضافة بشرط واحد في وقت واحد. وبهذه الطريقة، على الأقل تفصل بين فوضى من if.

وأعرف أن هذا موضوع قديم، ولكن لدي بعض بيثون 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 تحذير "خط مسنن بصريا مع نفس المسافة البادئة كخط المنطقي التالي"، رمز الفعلي على ما يرام تماما؟ انها ليست "الإفراط في الطعج؟"

... هناك أوقات أتمنى أن بيثون قمت قليلا الرصاصة وانتهت للتو مع الأقواس المعقوفة. أتساءل كم البق أدخلت قصد على مر السنين بسبب عرضي سوء تسنن ...

وجميع المشاركين التي توفر أيضا الشرطية متعددة لبيان إذا تماما كما هو قبيح كما قدمت المشكلة. كنت لا حل هذه المشكلة عن طريق القيام بنفس الشيء ..

وحتى الجواب PEP 0008 هو مثير للاشمئزاز.

وهنا هو نهج أكثر قابلية للقراءة حتى الآن

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

وتريد مني أن أكل كلماتي؟ إقناعي تحتاج الشرطية المتعددة وسوف طباعة حرفيا هذا وأكله للتسلية الخاص بك.

أعتقد أن حلzkanda سيكون جيدًا مع لمسة بسيطة.إذا كانت لديك شروطك وقيمك في قوائمها الخاصة، فيمكنك استخدام فهم القائمة لإجراء المقارنة، الأمر الذي من شأنه أن يجعل الأمور أكثر عمومية قليلاً لإضافة أزواج الشرط/القيمة.

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

وحزمة الشروط الخاصة بك في القائمة، ثم القيام شىء. مثل:

if False not in Conditions:
    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

وليس هناك أي سبب المسافة البادئة ينبغي أن يكون من مضاعفات الرقم 4 في هذه الحالة، على سبيل المثال انظر: «الانحياز مع فتح محدد":

HTTP: //google-styleguide.googlecode. كوم / إس / جذع / pyguide.html؟ showone = المسافة البادئة # المسافة البادئة

إليك طريقة أخرى:

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"')

وعادة ما تستخدم:

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

وإذا كان لدينا إذا وشرط آخر لديه لتنفيذ بيان متعددة داخل منه مما كنا يمكن أن يكتب مثل أدناه. كل عندما يكون لدينا إذا سبيل المثال آخر مع بيان واحد داخل منه.

وبفضل ذلك العمل بالنسبة لي.

#!/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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top