'if'문에서 여러 줄 조건을 스타일링합니까? [닫은]


677

때로는 ifs의 긴 조건 을 여러 줄로 나눕니다. 이를 수행하는 가장 확실한 방법은 다음과 같습니다.

  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 Python 패키지를 사용하여 PEP8 위반 에 대해 경고 할시기를 감지하는 경우 E125 오류를 사용하지 않도록 설정하거나 pep8패키지 기준 을 만족하는 형식화 솔루션을 찾아야 합니다. pep8패키지의 문제점 # 126는 엄격하게 PEP8 사양에 따라에 패키지를 고정에 관한 것입니다. 이 문제에 대한 토론에는 여기에서도 볼 수있는 몇 가지 스타일 제안이 포함됩니다.
akaihola

1
첫 번째 예의 경우, pep8은 "다음 논리 행과 같은 들여 쓰기가있는 E129 시각적 들여 쓰기 행"을 표시합니다.
Taylor Edmiston

이 질문은 매우 오래되었고 많은 견해를 가지고 있지만 분명한 의견에 근거합니다. "매우 매력적이지 않은"및 "매우 예쁘지 않은"이라는 언어는 아마도 정답이 요구 자의 미적 선호 (즉, 의견)에 가장 잘 맞는 답이라는 기준을 제시합니다. 나는 정확히 같은 질문을 할 수 있고 미학적 취향이 다른 것으로 인정하기 때문에 복제본이 아니라고 주장 할 수 있으며 다른 "올바른"답변으로 이어질 것입니다.
Z4-tier

@ Z4- 계층 : 예, 의견에 근거합니다. 그러나 그것은 12 년 전에 요청되었습니다. 그 당시에는 다른, 더 친절한 곳 이었습니다 . 최근 SO 표준이 변경되어 다운 보트를 축적하고 있습니다. 아직도,> 1 백만 회 이상 본 결과, 그것이 세계에서 해보다 더 잘되고 있기를 바랍니다. 나는 오늘 같은 질문에 대해 궁금해하는 사람들, 인터넷 검색,이 토론에 착륙하고 그들의 생각을 교정하는 것이 유용한 것을 확실히 알 수 있습니다. 선택할 수있는 많은 투표가 있습니다.
Eli Bendersky

@EliBendersky는 완전히 동의합니다. SO가 지속적인 정체성 위기를 겪고있는 것과 같습니다. "규칙"에는 맞지 않지만 (유효한 답변의 수는 그 증거 임), 가치를 더한다는 것은 분명합니다. 모든 것이 평등하기 때문에 나는 견해가 내 관점과 다를지라도 코딩 스타일에 대해 명확하고 합리적인 견해를 개발 한 사람과 함께 일하고 싶습니다.
Z4-tier

답변:


750

두 번째 조건부 라인에는 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
PEP 8에서는 후행 \ 솔루션을 권장하지 않습니다. 한 가지 이유는 \ 다음에 공백이 실수로 추가되면 편집기에 표시되지 않을 수 있고 코드가 구문 상 올바르지 않게되기 때문입니다.
Eric O Lebigot

14
스타일 가이드에 따르면 "길이가 긴 줄은 괄호로 묶어 여러 줄로 나눌 수 있습니다. 줄 연속에 백 슬래시를 사용하는 것보다 우선적으로 사용해야합니다." 여기에서 볼 수 있습니다 : python.org/dev/peps/pep-0008/#maximum-line-length
joshcartme

8
@joshcartme PEP가 hg.python.org/peps/rev/7a48207aaab6 에서 백 슬래시를 명시 적으로 억제하지 않도록 변경되었습니다 . 답변을 업데이트하겠습니다.
할리 홀콤

3
감사합니다. 예를 들어 권장하지 않으므로 예제도 업데이트하는 것이 좋습니다. 나는 이것을 스스로 알아 내려고 노력했고 당신의 대답과 스타일 가이드 (따라서 나의 의견) 사이의 불일치로 혼란 스러웠다. 나는 단지 pedantic하려고하지 않았습니다.
joshcartme

3
PEP 8은 이제 and및 이후에도 중단되지 않습니다 if.
virtualxtc

124

나는 단순히 AND 또는 OR 인 퇴화 된 경우에 다음에 의지했습니다.

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

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

그것은 몇자를 면도하고 조건에 미묘함이 없음을 분명히합니다.


4
이것은 흥미로운 접근법입니다. 긴 조건 문제는 다루지 않습니다
Eli Bendersky

20
단락에 신경 쓰지 않아도 괜찮습니다.
Constantin

63
shortcirtuiting이 항상 빠른 것은 아닙니다. 좋은 코딩 방법은 아니지만 다음과 같은 기존 코드가있을 수 있습니다 if destroy_world and DestroyTheWorld() == world_is_destroyed: .... 자, 이제 우연히 세상을 파괴했습니다. 어떻게 대처 했습니까?
Aaron

4
나는 이것이 너무 많은 공언을 가지고 놀랐습니다. 이 답변은 여러 줄 조건부 스타일 지정에 대한 원래 질문을 완전히 무시합니다 .
Przemek D

2
이 표현은 게으르지 않습니다. 따라서 일부 보호 조건에 이어 실패 할 수있는 조건과 동일하지 않습니다.
eugene-bright

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()

예, 우리는 명확성을 위해 약간의 수직 부동산을 거래하고 있습니다. 그만한 가치가 있습니다.


19
이것은 아름답 지 않거나 PEP8과 호환되지 않는 것 같습니다. PEP8에 따르면 이진 연산자를 돌파하기 위해 선호되는 장소 는 연산자 가 and아니라 연산자 뒤에 있습니다. or
Chris Medrela

7
@ChristopherMedrela는 그 이유를 설명합니까? 내가 논리 연산자 전에 줄 바꿈을 배치 생각하는 것은 많은 명확
Norill 폭풍우

4
노드의 세계에서는 oprerator를 최우선으로 생각하는 것이 일반적입니다. 이론적 근거는 적어도 서양 문화에서는 왼쪽에있는 것보다 오른쪽에있는 것보다 훨씬 빠르게 인식하고 읽는다는 것입니다. 잊어 버린 쉼표로 인해 자동 오류가 발생할 수있는 JavaScript에서 매우 유효합니다.
tomekwi

11
제발 이러지 마 그것을하지 않습니다뿐만 아니라 PEP8하지만 열심히 당신이 체인 있다는 논리 연산을 결정 할 수 있습니다. 코드 검토를 통해 내 책상에 오면이 문제를 해결할 것입니다.
Urda

11
PEP8의 현재 버전에서, 이진 연산자의 앞뒤에있는 것은 허용되는 것으로 간주 되고 연산자가 새로운 코드에 대해 더 나은 것으로 간주되기 전에.
Soren Bjornstad

31

나는 매우 큰 if 조건이있을 때이 스타일을 선호합니다.

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

2
당신이 그들을 추적 할 수있는 곳에 들여 쓰기를 유지하기 위해 +1. 나는 파이썬을 좋아하고 그것을 많이 사용하지만, 너무 들여 쓰기를 강요하여 끊임없이 화가납니다. 멀티 라인은 잘 수행 된 경우에도 실제로 미학을 파괴합니다.
mightypile

4
Note을 갖는 andor라인의 시작에서 운영하는 위반 PEP 0008 미국, "선호하는 장소는 바이너리 연산자 연산자 후, 아니 그 전에 주위를 깰 수 있습니다." . 나는 if 조건을 본문과 분리하기 위해 닫는 대괄호와 콜론을 자체 줄에 두는 것을 좋아합니다 (PEP-0008 준수를 위해 부울 연산자를 줄 끝에 유지 하면서이 작업을 완벽하게 수행 할 수 있습니다).
Mark Amery

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.(Knuth의 스타일은 연산자로 라인을 시작합니다).
cowbert

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 개 여분의 라인 :-)
엘리 Bendersky

wouldnt가 아니라 반복적 인 루프, 기능 wouldnt가 작업 공정을 뭔가를하고 ... 그리고로 정말 일 - 추한
메즈

9
브라이언, 부분적으로 동의하지 않습니다. 계산의 중간 결과에 변수를 사용하면 코드를 더 쉽게 이해할 수 있으며 컴파일 된 언어에서는 성능에 영향을 미치지 않습니다. 성능이 그렇게 중요하다면 파이썬을 전혀 사용하지 않지만 파이썬에서는 아마 할 것입니다.
Mark Baker

1
@MarkBaker Martin Fowlers "Refactoring"을 읽을 때까지 나는 당신이 쓴 것에 동의했다. 그는 이러한 중간 변수가 이익보다 더 많은 해를 끼친다는 훌륭한 주장을 제시합니다. 후속 리팩토링을 금지합니다. 그것들없이 수행하면보다 기능적인 프로그래밍 스타일이 생겨 리팩토링에 적합합니다. 이것은 나를 놀라게했지만, 그가 옳다고 생각하고 그 이후로 두 번 이상 사용하더라도 내 코드에서 이와 같은 불필요한 중간체를 제거하려고 노력했습니다.
Jonathan Hartley

2
좋은데 왜 낙타 케이스?! :)
Leonid Shvechikov

19

and키워드를 두 번째 줄로 옮기고 조건을 포함하는 모든 줄을 4 개가 아닌 2 개의 공백으로 들여 쓰는 것이 좋습니다 .

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

이것이 바로 코드 에서이 문제를 해결하는 방법입니다. 키워드를 줄의 첫 단어로 사용하면 조건을보다 쉽게 ​​읽을 수 있으며 공간 수를 줄이면 조건과 동작을 더욱 구분할 수 있습니다.


9
나는 Gries 또는 Djikstra 어딘가에서 논리 연산자를 라인의 맨 앞에 배치하여 더 눈에 잘 띄게 만들었습니다. 저는 90 년대부터 그렇게 해왔습니다. 도움이됩니다.
S.Lott

7
스타일 가이드는 줄의 끝에 조건부를 넣도록 권장합니다.
Harley Holcombe

3
나는 이것에 동의하지 않았지만 사실입니다. 결국 가이드 일뿐입니다.
DzinX

8
PEP8은 더 이상 라인의 끝에 조건을 설정 하지 않는 것이 좋습니다 .
Soren Bjornstad

14

PEP 0008 (Python의 공식 스타일 가이드)을 인용 할 가치가 있습니다 .

if문장 의 조건부 부분이 여러 줄에 걸쳐 쓰여질만큼 충분히 길면 두 문자 키워드 (예 :) if와 단일 공백, 여는 괄호의 조합이 자연스럽게 생성 된다는 점에 주목할 가치가 있습니다. 멀티 라인 조건부의 후속 라인에 대해 들여 쓰기 이것은 if-statement 안에 중첩 된 들여 쓰기 된 코드 세트와 시각적으로 충돌 할 수 있으며 , 자연스럽게 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()

위의 인용문에서 "제한되지 않음"에 유의하십시오. 스타일 가이드에서 제안 된 접근 방식 외에도이 질문에 대한 다른 답변에서 제안 된 접근 방식 중 일부도 허용됩니다.


PEP8의 경우 +1 이것은 한다고 이 (실질적으로 말하기) 때문에, 공식 파이썬 스타일 가이드를받을 수 있습니다.
Michael-Clay는 어디에 있습니까 Shirky

2
또한 PEP8은이 PEP가 if-문 내부의 중첩 된 스위트와 이러한 조건부 라인을 시각적으로 더 구분하는 방법에 대한 명시적인 입장을 취하지 않기 때문에 입장을 명시 적으로 언급합니다 . 이 상황에서 허용되는 옵션에는 다음이 포함되지만 이에 국한되지는 않습니다. ... (snipped) 논쟁을 멈추고 원하는 것을 선택하십시오!
RayLuo

7

여기에 내가하는 일은 "all"과 "any"가 iterable을 허용한다는 것을 기억하십시오. 그래서리스트에 긴 조건을 넣고 "all"이 작동하게합니다.

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과 충분히 다르게 보입니다.


그러나 계속 행은 여전히 ... 다음 논리 행에서 자신을 구분하지 않습니다
크리스 Medrela에게

1
이는 PEP 0008 위반입니다 ( "이진 연산자를 돌파하기 위해 선호되는 위치는 연산자가 아니라 연산자 뒤에 있습니다" ). 물론 당신이 돌보는 것은 당신에게 달려 있습니다.
Mark Amery

1
또한 이것은 더 이상 내가 선호하는 솔루션이 아닙니다. ;)
Marius Gedminas

4

@krawyoti의 말에 덧붙여서 ... 장기적인 조건은 읽기 어렵고 이해하기 어렵 기 때문에 냄새가납니다. 함수 나 변수를 사용하면 코드가 더 명확 해집니다. 파이썬에서는 세로 공간을 사용하고 괄호를 묶고 각 행의 시작 부분에 논리 연산자를 배치하여 표현식이 "부동"처럼 보이지 않는 것을 선호합니다.

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

while루프 에서와 같이 조건을 두 번 이상 평가해야하는 경우 로컬 기능을 사용하는 것이 가장 좋습니다.


1
이 외에도 추가 변수를 만드는 대신 true 또는 false를 반환하는 함수 또는 람다를 선언 할 수 있습니다.
Techdragon

@Techdragon 조건이 다른 곳에있는 경우 람다 블록에 넣으려면 람다 블록의 이름을 지정해야 나중에 if 조건에서 참조 할 수 있습니다. 람다의 이름이 지정된다면, 왜 람다가 일반 함수가 아닌가? 나는 개인적으로이 축소 된 부울 표현을 좋아합니다.
스리 Kadimisetty

프로그램 제어 흐름을 이해하기 위해 스키밍 할 때 가독성이 향상되고 정신 소화가 용이하도록 대부분의 경우에 일반적으로 함수를 사용하는 이유에 동의합니다. 나는 사람들이 특히 공간을 의식하는 경우 '작은'옵션도 존재하도록하기 위해 람다를 언급합니다.
Techdragon

4

개인적으로 저는 긴 if 문에 의미를 추가하고 싶습니다. 적절한 예제를 찾으려면 코드를 검색해야하지만 다음은 염두에 두어야 할 첫 번째 예입니다. 많은 변수에 따라 특정 페이지를 표시하려는 기발한 논리가 발생한다고 가정 해 봅시다.

영어 : "로그인 한 사용자가 관리자 교사가 아니라 정규 교사이고 학생이 아닌 경우 ..."

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

물론 이것은 잘 보일지 모르지만 if 문을 읽는 것이 많은 작업입니다. 논리를 의미있는 레이블에 할당하는 것은 어떻습니까? "라벨"은 실제로 변수 이름입니다.

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

이것은 어리석은 것처럼 보일 수 있지만 교사 패널을 표시하거나 사용자가 기본적으로 다른 특정 패널에 액세스 할 수있는 경우에만 다른 항목을 표시하려는 또 다른 조건이있을 수 있습니다.

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

변수를 사용하여 논리를 저장하고 레이블을 지정하지 않고 위의 조건을 작성하십시오. 매우 복잡하고 읽기 어려운 논리 문으로 끝날뿐만 아니라 자신을 반복했습니다. 합리적인 예외가 있지만 다음을 기억하십시오 : 스스로 반복하지 마십시오 (건조).


3

"all"과 "any"는 동일한 유형의 여러 조건에 적합합니다. 그러나 그들은 항상 모든 조건을 평가합니다. 이 예에 표시된대로 :

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
잘못되었습니다! 그들은 당신 이하기 때문에 수 있습니다. [c1, c2]에서 f에 대해 모든 (f ()를 시도하십시오.)
habnabit 2016 년

2
나는 그가 쉽게 무언가를 인쇄 할 수 있기 때문에 함수를 예로 들어 사용하고 있다고 생각합니다. 우리가 목록에 제공된 일련의 임의의 표현식을 고려하고 있다면 all(), 각각을 람다로 감싸고 f()트릭을 사용하지 않는 한 모두 평가됩니다. 다시 말해, Aaron : Anders가 호출 가능한 것을 특정한 예로 사용하여 일반적인 조건에 대해 이야기하려고했다고 생각합니다. 그러나 rejoinder는 함수에만 적용됩니다.
Brandon Rhodes

3

(고정 너비 이름은 실제 코드를 대표하지 않으므로 적어도 실제 코드를 나타내지 않기 때문에 식별자를 약간 수정했습니다. 최소한 실제 코드는 아닙니다.)

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

이것은 "and"및 "or"에 대해 잘 작동하지만 (두 번째 줄에있는 것이 중요 함) 다른 긴 조건에서는 훨씬 적습니다. 다행히 전자가 더 일반적인 경우 인 반면 후자는 종종 임시 변수로 쉽게 다시 작성됩니다. (일반적으로 어렵지는 않지만 다시 작성할 때 "및"/ "또는"단락을 유지하는 것은 어렵거나 훨씬 덜 명확하거나 읽을 수 있습니다.

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

최근에 나는 And와 Or 비교를 거의 섞지 않기 때문에 alland와 any함수를 선호 하고 있습니다.

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

하나의 iterable을 전달하는 것을 잊지 마십시오! N- 인수를 전달하는 것이 올바르지 않습니다.

참고 : 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
또한 pylint의 스톡 구성은 if에서 줄 연속으로 들여 쓰기를 원한다는 점을 지적해야합니다. 이 구성표를 사용하지 못하도록 설득했습니다.
ThorSummoner

2

상태와 몸 사이에 빈 줄을 추가로 삽입하고 나머지는 정식 방식으로 수행하면 어떻게됩니까?

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

    do_something

추신 : 나는 항상 공백이 아닌 탭을 사용합니다. 미세 조정할 수 없습니다 ...


3
특히 조건부 본문이 길면 혼란 스럽습니다.
Eli Bendersky

나는 캡슐화와 들여 쓰기가 긴 줄을 혼란스럽게하는 Eli에 동의합니다. 또한, 새로운 규칙은 것입니다 andor문이 다음 행에서 시작해야
virtualxtc

2

내가 보통하는 일은 :

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

이런 식으로 닫는 중괄호와 콜론은 시각적으로 우리의 상태의 끝을 표시합니다.


1
거의 맞습니다. PEP 8은 이제 and또는 이전에 차단을 권장합니다 or.
virtualxtc

2

if 문에 대해 다중 조건을 제공하는 모든 응답자는 제시된 문제만큼이나 추악합니다. 동일한 작업을 수행하여이 문제를 해결할 수 없습니다.

PEP 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 댓글을 삭제 해 주셔서 감사합니다. 귀하의 접근 방식이 OP의 질문에 답변하지 않는다고 지적하고 싶습니다. 제공 한 코드는 해당 코드에 적용 할 수 없습니다. 달리 생각하면 요점을 증명하기 위해 접근 방식으로 다시 포맷 된 OP 코드를 추가해야합니다.
Jeyekomon

그것은 받아 들일만한 대답은 아니지만 분명히 다른 접근법입니다 (다른 사람들은 동의합니다). 그래서 대안적인 답변을 장려 했으므로 논쟁의 정확한 내용은 무엇입니까? 적절한 관심이 필요한 경우 자신의 질문에 명확하게 답하십시오. 추신 : 나는 SO 모드가 아니며, 주석을 제거 할 수 없습니다
Stoff

2

@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

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

그것이 당신에게 효과적이라면 Dunno이지만, 고려해야 할 또 다른 옵션입니다. 한 가지 더 방법이 있습니다.

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 개의 들여 쓰기 공간 (bool)을 얻으므로 모든 조건을 세로로 정렬 할 수 있으며 if 문의 본문을 들여 쓸 수 있습니다 분명한 방법. 이것은 또한 부울 연산자의 단락 평가의 이점을 유지하지만, 기본적으로 아무것도 수행하지 않는 함수 호출의 오버 헤드를 추가합니다. 인수를 반환하는 모든 함수가 부울 대신 여기에서 사용될 수 있다고 주장 할 수는 있지만, 내가 말했듯이 그것은 단지 아이디어 일 뿐이며 궁극적으로 맛의 문제입니다.

이 문제를 작성하고 "문제"에 대해 생각 하면서 함수 호출의 오버 헤드를 제거하는 또 다른 아이디어를 생각해 냈습니다 . 여분의 괄호 쌍을 사용하여 복잡한 조건에 들어갔다고 표시해 보시겠습니까? if 문의 본문과 관련하여 하위 조건을 멋지게 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

이 스레드가 오래되었다는 것을 알고 있지만 Python 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, 확장 하시겠습니까? PEP 8
xorsyst

이것은 실제로 줄 연속에 유효한 경우입니다. IMPO 괄호는 튜플 또는 함수 호출을 나타냅니다. OP의 사용은 C와 매우 유사하므로 가능하면 파이썬 구문을 선호합니다. 그래도 \는 보편적으로 선호되지 않는다는 것을 인정합니다.
Dima Tisnek

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 가이드는 OP에 언급 된 '가장 확실한 방법'과 일치 하는 복잡한 조건의 예도 제공 합니다 . 이 가이드는 긴 "if"형식을 명시 적으로 권장하지는 않지만
Anton Strogonoff

0

다른 접근 방식이 있습니다.

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

또한 목록에 다른 조건을 추가하여 if 문을 변경하지 않고도 다른 조건을 쉽게 추가 할 수 있습니다.

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

0

나는 보통 다음을 사용합니다.

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

0

if & else 조건이 내부에서 여러 명령문을 실행 해야하는 경우 아래와 같이 작성할 수 있습니다. 우리가 그 안에 하나의 진술로 다른 예를 가지고 있다면 매번.

고맙습니다.

#!/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. 다단계 조건 불필요

그것이 당신 모두를 돕기를 바랍니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.