파이썬`x x가 None이 아닌 경우`또는`x가 아닌 경우`가 아닌가?


746

나는 항상 if not x is None버전이 더 명확 하다고 생각 했지만 Google의 스타일 가이드PEP-8은 모두를 사용 if x is not None합니다. 약간의 성능 차이가 있습니까? (그렇지 않다고 가정합니다) 하나가 실제로 맞지 않는 경우가 있습니까 (다른 하나는 내 컨벤션에서 확실한 승자가됩니까)?

* 나는 단지 싱글 톤이 아닌 싱글 톤을 언급하고있다 None.

... 없음과 같은 싱글 톤을 비교합니다. 사용 여부입니다.


8
is not그 자체의 연산자입니다. 처럼 !=. 당신이 선호 not x is None한다면 당신은 또한 not a == b이상 을 선호해야합니다 a != b.
Tomasz Gandor

@TomaszGandor 나는 더 이상 이것에 대한 의견을 얻지 못했지만 not x is None(여기의 대답은 저를 설득했습니다)-그러나 그것이 not a == b파이썬에서 선호하는 스타일 이라는 점 은 주목할 가치가 a != b있습니다.
orokusaki

4
@orokusaki는 not a == b실제로 선호하는 스타일입니까? 나는 그런 식으로 그런 짓을 한 적이 없으며 사람들이 모두 사용하는 것처럼 보입니다 !=.
Mike-SMT

2
@orokusaki에서 파이썬 가독성 카운트가 하나의 연산자를 사용하는 선호하는 스타일 그래서 !=대신에 두 개의 사업자가 not, ==.
Jeyekomon

답변:


995

동일한 바이트 코드로 컴파일되므로 성능 차이가 없습니다.

Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
...    return x is not None
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> def g(x):
...   return not x is None
...
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

독창적으로, 나는 피하려고합니다 not x is y. 컴파일러는 항상이를 컴파일러로 취급하지만 not (x is y)인간 독자는 구문을 다음과 같이 오해 할 수 있습니다 (not x) is y. 내가 쓰면 x is not y모호성이 없습니다.


103
같은 인간 독자가 그렇게 생각하지 않는 한 x is (not y). 그러나 나는 당신의 다른 추론에 대해 당신에게 동의하는 경향이 있습니다.
Etaoin

24
또한 "이 아니라"는이 문맥에서 "모호하지 않은 경우 b는 없음 :"대 "a가 아닌 경우 b는 없음 :"
Gordon Wrigley

45
연산자는 "aint"여야합니다
bean

216

Google과 Python 의 스타일 가이드는 모두 모범 사례입니다.

if x is not None:
    # Do something about x

사용 not x하면 원하지 않는 결과가 발생할 수 있습니다.

아래를보십시오 :

>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0]         # You don't want to fall in this one.
>>> not x
False

파이썬 에서 True또는 False파이썬에서 어떤 리터럴이 평가되는지 알고 싶을 것입니다.


아래 의견을 편집하십시오.

방금 테스트를 더했습니다. 먼저 not x is None부정하지 않고에 x비교합니다 None. 실제로, is그런 식으로 사용 하면 연산자가 우선 순위가 높은 것 같습니다 .

>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False

그러므로 not x is None제 솔직한 의견으로는 피하는 것이 가장 좋습니다.


추가 편집 :

난 그냥 한 테스트하고 bukzor의 의견이 올바른지 확인할 수 있습니다. (적어도 다른 방법으로는 증명할 수 없었습니다.)

이는 if x is not None정확한 결과를 의미 합니다 if not x is None. 나는 정정되었다. 고마워 bukzor.

그러나 내 대답은 여전히 ​​선언합니다 : traditional을 사용하십시오if x is not None .:]


131

프로그래머가 먼저 이해할 수 있고 컴파일러 나 인터프리터가 이해할 수 있도록 코드를 작성해야합니다. "is not"구문은 "not is"보다 영어와 비슷합니다.


33

파이썬 if x is not None또는 if not x is None?

TLDR : 바이트 코드 컴파일러는 그것들을 모두 분석하기 x is not None때문에 가독성 을 위해을 사용하십시오 if x is not None.

가독성

우리는 성능에 대한 프로그래밍의 다양한 패러다임의 인간 가독성, 사용성 및 정확성과 같은 것을 중요하게 생각하기 때문에 Python을 사용합니다.

파이썬은 특히이 문맥에서 가독성을 최적화합니다.

바이트 코드 파싱 및 컴파일

not 더 약하게 바인딩 이상은 is, 그래서 여기에 논리적 차이가 없다. 설명서를 참조하십시오 :

x와 y가 동일한 객체 인 경우에만 연산자 isis not객체 동일성 테스트 : x is ytrue입니다. x is not y역 진리 값을 산출합니다.

이 언어 is not는 파이썬 문법 에서 언어의 가독성 향상을 위해 특별히 제공 됩니다.

comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

그리고 그것은 문법의 단일 요소이기도합니다.

물론 동일하게 구문 분석되지는 않습니다.

>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"

그러나 바이트 컴파일러는 실제로 변환합니다 not ... is합니다 is not:

>>> import dis
>>> dis.dis(lambda x, y: x is not y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

가독성을 위해 의도 한대로 언어를 사용하려면을 사용하십시오 is not.

그것을 사용 하지 않는 것이 현명 하지 않습니다 .


" not바인딩은보다 약하게 바인딩 is되므로 여기에는 논리적 차이가 없습니다."-파이썬이 논리적 및 대수적 아이덴티티를 유지하도록 강제 할 필요가 없다는 점을 제외하면 ( (1 + 2)*3와 동일하게 평가할 본질적인 이유는 없습니다 1*3 + 2*3). 분명히 파이썬은 바람을 피우고 최적화하고 UNARY_NOT있습니다.
Alexey

30

사람들이하는 것보다 답이 더 간단합니다.

기술적 인 이점은 없으며 "x는 y가 아닙니다"는 다른 사람들이 사용 하는 것이므로 확실한 승자가됩니다. "영어처럼 보인다"는 문제가되지 않습니다. 모두가 그것을 사용합니다. 즉, 파이썬을 사용하지 않는 중국어 사용자조차도 파이썬의 모든 사용자가 한 눈에 이해하게 될 것입니다. 약간의 덜 일반적인 구문은 구문 분석을 위해 몇 번의 추가 두뇌 사이클이 필요합니다.

적어도이 분야에서 달라지기 위해 다르지 마십시오.


11

is not연산자의 결과 부정을 통해 바람직 is문체 이유로한다. " if x is not None:"는 영어처럼 읽지 만 " if not x is None:"은 연산자 우선 순위를 이해해야하며 영어처럼 읽지 않습니다.

내 돈이 성능 차이가 있다면 is not, 그 기술을 선호하는 결정에 대한 동기가 아닐 것입니다. 분명히 구현에 따라 다릅니다. 이후 is재정의하지, 어쨌든 어떤 구분을 최적화하기 쉬워야한다.


9

개인적으로 사용합니다

if not (x is None):

이것은 모든 프로그래머, 심지어 파이썬 문법 전문가가 아니더라도 모호하지 않고 즉시 이해됩니다.


5
내가 동의하는 공정한 주장이지만 관용적 스타일을 따르는 주장이 더 강력하다고 생각합니다.
clacke

2

if not x is None다른 프로그래밍 언어와 더 비슷하지만 if x is not None분명히 더 명확하게 들립니다 (영어에서는 문법적으로 정확합니다).

그것은 그것이 나에게 더 선호되는 것 같습니다.


0

x is not y 훨씬 더 읽기 쉬운 코드를 생성하기 위해 연산자의 코드 처리 우선 순위를 결국 작성하는 방법보다 생각 하기 쉬운 읽기 형식을 선호합니다 .

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