Development Tip

파이썬`x가 None이 아니면`아니면`x가 None`이 아니면?

yourdevel 2020. 9. 30. 11:35
반응형

파이썬`x가 None이 아니면`아니면`x가 None`이 아니면?


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

* 나는 단지 None.

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


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

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모호성이 없습니다.


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

Python 에서 True또는 리터럴이 평가되는 내용을보고 싶을 수 있습니다 False.

아래 댓글 수정 :

좀 더 테스트를했습니다. 먼저 not x is None부정하지 않고 . 사실, 연산자는 이런 식으로 사용할 때 더 높은 우선 순위를 갖는 것 같습니다 .xNoneis

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

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

추가 편집 :

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

This means if x is not None has the exact result as if not x is None. I stand corrected. Thanks bukzor.

However, my answer still stands: Use the conventional if x is not None. :]


Code should be written to be understandable to the programmer first, and the compiler or interpreter second. The "is not" construct resembles English more closely than "not is".


The answer is simpler than people are making it.

There's no technical advantage either way, and "x is not y" is what everybody else uses, which makes it the clear winner. It doesn't matter that it "looks more like English" or not; everyone uses it, which means every user of Python--even Chinese users, whose language Python looks nothing like--will understand it at a glance, where the slightly less common syntax will take a couple extra brain cycles to parse.

Don't be different just for the sake of being different, at least in this field.


Python if x is not None or if not x is None?

TLDR: The bytecode compiler parses them both to x is not None - so for readability's sake, use if x is not None.

Readability

We use Python because we value things like human readability, useability, and correctness of various paradigms of programming over performance.

Python optimizes for readability, especially in this context.

Parsing and Compiling the Bytecode

The not binds more weakly than is, so there is no logical difference here. See the documentation:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.

The is not is specifically provided for in the Python grammar as a readability improvement for the language:

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

And so it is a unitary element of the grammar as well.

Of course, it is not parsed the same:

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

But then the byte compiler will actually translate the not ... is to 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

So for the sake of readability and using the language as it was intended, please use is not.

To not use it is not wise.


The is not operator is preferred over negating the result of is for stylistic reasons. "if x is not None:" reads just like English, but "if not x is None:" requires understanding of the operator precedence and does not read like english.

If there is a performance difference my money is on is not, but this almost certainly isn't the motivation for the decision to prefer that technique. It would obviously be implementation-dependent. Since is isn't overridable, it should be easy to optimise out any distinction anyhow.


Personally, I use

if not (x is None):

which is understood immediately without ambiguity by every programmer, even those not expert in the Python syntax.


if not x is None is more similar to other programming languages, but if x is not None definitely sounds more clear (and is more grammatically correct in English) to me.

That said it seems like it's more of a preference thing to me.


I would prefer the more readable form x is not y than I would think how to eventually write the code handling precedence of the operators in order to produce much more readable code.

참고URL : https://stackoverflow.com/questions/2710940/python-if-x-is-not-none-or-if-not-x-is-none

반응형