“foo is None”과“foo == None”사이에 차이점이 있습니까?


217

다음과 같은 차이점이 있습니까?

if foo is None: pass

if foo == None: pass

대부분의 Python 코드 (및 내가 직접 작성한 코드)에서 본 규칙은 전자이지만 최근에는 후자를 사용하는 코드를 발견했습니다. NoneType의 인스턴스 (및 유일한 인스턴스 인 IIRC)는 없습니다. 문제가되지 않습니까? 상황이있을 수 있습니까?

답변:


253

isTrue동일한 객체 인스턴스를 비교하면 항상 반환

반면 ==최종적으로 결정되는 __eq__()방법


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

51
None이 싱글 톤이므로 "None is None"이 항상 True임을 추가 할 수 있습니다.
전자 Satis

43
그리고 is연산자를 사용자 정의 할 수 없도록 추가 할 수도 있습니다 (사용자 정의 클래스에 의해 오버로드 됨).
martineau

@study이 메소드 __eq__(self)==Python 객체에서 사용될 때 처리 방법을 결정하는 특수 내장 메소드입니다 . 여기서는 ==유형의 객체에 사용될 때 Foo항상 true를 반환 하도록 재정의했습니다 . is연산자 에는 동등한 방법이 없으므로 같은 방식으로 동작을 is변경할 수 없습니다.
Brendan

foo 클래스의 정의에 생성자, 즉 init 함수 가 없기 때문 입니까?
공부하십시오

49

객체의 아이덴티티와 동등성 을 읽을 수 있습니다 .

'is'문은 객체 식별에 사용되며 객체가 동일한 인스턴스 (메모리의 동일한 주소)를 참조하는지 확인합니다.

그리고 '=='문은 동등 (동일한 값)을 나타냅니다.


흠, 파이썬에서 외부 함수를 호출하는 방법에
Pat

방금 시도했습니다 a=1;b=1;print(a is b) # True. a is b그들이 2 개의 다른 객체 (메모리의 다른 주소) 인 것처럼 보이지만 왜 사실로 판명됩니까?
Johnny Chiu

24

주의 사항 :

if foo:
  # do something

인가 되지 정확히 같은 :

if x is not None:
  # do something

전자는 부울 값 테스트이며 다른 상황에서 거짓으로 평가 될 수 있습니다. 빈 컨테이너, 부울 값과 같은 부울 값 테스트에서 거짓을 나타내는 여러 가지가 있습니다. 이 상황에서는 아무도 거짓으로 평가되지 않지만 다른 것들도 거짓으로 평가됩니다.


12

(ob1 is ob2) 동일 (id(ob1) == id(ob2))


6
...하지만 (ob is ob2) 훨씬 빠릅니다. Timeit은 "(a is b)"는 루프 당 0.0365 usec이고 "(id (a) == id (b))"는 루프 당 0.153 usec라고 말합니다. 4.2 배 더 빠름!
AKX

4
is버전은 더 함수 호출, 그리고 전혀 파이썬 인터프리터 속성 조회를 필요로하지 않는다; ob1이 실제로 ob2이면 인터프리터는 즉시 응답 할 수 있습니다.
u0b34a0f6ae

17
아니 그렇지 않아. {} is {}거짓과 id({}) == id({})할 수있다 (그리고 있다 CPython의에서) 사실. 참조 stackoverflow.com/questions/3877230
표트르 Dobrogost

12

그 이유 foo is None는 자신 __eq__을 정의하고 오브젝트를 없음과 동일하게 정의하는 오브젝트를 처리 할 수 ​​있기 때문에 선호되는 방법입니다 . 따라서 foo is None사실인지 확인해야 할 경우 항상 사용 하십시오 None.


8

동일한 객체는 물론 동일하기 때문에 차이가 없습니다. 그러나 PEP 8 은 다음과 같이 사용해야합니다 is.

없음과 같은 싱글 톤과의 비교는 항상 평등 연산자를 사용하거나 수행하지 않아야합니다.


7

is평등이 아닌 정체성을 테스트합니다 . 당신의 진술을 위해 foo is none, 파이썬은 단순히 객체의 메모리 주소를 비교합니다. "같은 객체에 대해 두 개의 이름이 있습니까?"라는 질문을합니다.

==다른 한편으로, __eq__()방법에 의해 결정된 평등을 시험한다 . 정체성에 관심이 없습니다.

In [102]: x, y, z = 2, 2, 2.0

In [103]: id(x), id(y), id(z)
Out[103]: (38641984, 38641984, 48420880)

In [104]: x is y
Out[104]: True

In [105]: x == y
Out[105]: True

In [106]: x is z
Out[106]: False

In [107]: x == z
Out[107]: True

None싱글 톤 연산자입니다. 그래서 None is None항상 사실이다.

In [101]: None is None
Out[101]: True

5

None의 경우 동등성 (==)과 동일성 (is)간에 차이가 없어야합니다. NoneType은 아마도 동일성을 위해 동일성을 반환합니다. None은 NoneType으로 만들 수있는 유일한 인스턴스이므로 (이것이 사실이라고 생각합니다) 두 작업은 동일합니다. 다른 유형의 경우 항상 그런 것은 아닙니다. 예를 들면 다음과 같습니다.

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

리스트에 기본 아이디 반환이 아닌 비교 연산이 있으므로 "같음"으로 표시됩니다.


5

@ 제이슨 :

나는 라인을 따라 더 많은 것을 사용하는 것이 좋습니다

if foo:
    #foo isn't None
else:
    #foo is None

foo가 실제로 부울 값 (예 : 0 또는 1)을 나타내지 않는 한 "if foo :"를 사용하는 것을 좋아하지 않습니다. foo가 문자열이나 객체 또는 다른 것이라면 "if foo :"가 작동 할 수 있지만 게으른 지름길처럼 보입니다. x가 없음인지 확인하려면 "x가 없음 인 경우 :"라고 말합니다.


"if var"를 사용하여 빈 문자열 / 목록을 확인하는 것이 좋습니다. 부울 변환은 잘 정의되어 있으며 더 나은 성능을 발휘하는 코드는 적습니다. 예를 들어 "if len (mylist) == 0"을 수행 할 이유가 없습니다.
truppo

잘못된. foo = ""라고 가정하십시오. 그런 다음 if foo거짓을 반환하고 주석 #foo is None이 잘못되었습니다.
blokeley

downvoters 참고 사항-내 대답은 이후 삭제 된 의견에 인용하고 동의하지 않습니다. 당신이 경우 하지 않습니다 내 대답에 코드처럼, 당신은 필요 upvote에 . :-)
Graeme Perrow

2

더 자세한 내용은 :

  1. is절은 실제로 두 개의 object메모리 위치가 같은지 여부를 확인합니다 . 즉, 둘 다 동일한 메모리 위치를 가리키고 동일한 지 여부 id입니다.

  2. 1의 결과로 is, 두 어휘 표현 object이 동일한 속성 (속성 속성 ...) 을 갖는지 여부를 보장합니다.

  3. 같은 원시 타입의 인스턴스는 bool, int, string(일부 예외), NoneType동일한 값을 갖는 것은 항상 동일한 메모리 위치에있을 것이다.

예 :

>>> int(1) is int(1)
True
>>> str("abcd") is str("abcd")
True
>>> bool(1) is bool(2)
True
>>> bool(0) is bool(0)
True
>>> bool(0)
False
>>> bool(1)
True

그리고 NoneType파이썬의 "look-up"테이블에 하나의 인스턴스 만 가질 수 있기 때문에 전자와 후자는 코드를 작성한 개발자의 프로그래밍 스타일에 더 가깝습니다. 다른 하나를 선택하십시오.


2
이것을 읽는 사람 : some_string is "bar"문자열을 비교 하는 데 사용하지 마십시오 . 그렇게하는 단일 수락 가능한 이유가 없으며, 예상치 못한 경우 중단됩니다. CPython은 내용이 동일한 두 개의 불변 객체를 만드는 것이 어리 석다는 것을 알고 있기 때문에 종종 작동한다는 사실이 간단합니다. 그럼에도 불구하고 일어날 수 있습니다.
ThiefMaster

@ThiefMaster는 답이 잘못 해석되는 경향이 있습니까? 그러나 다시 읽었을 때 나는 그것을 찾을 수 없었습니다 ( "일부 예외"에 대한 언급과 함께). 귀하의 진술은 문자열에만 해당되며 그렇지 않습니다 int.
출혈 손가락

실제로는 아니지만 답변에 해당 예가 있으므로 실제로 사용하는 것이 좋지 않다는 것을 사용자에게 경고하는 것이 좋습니다. 아마도 그 줄 뒤에 "# cpython specific / not secure"같은 것을 추가하십시오.
ThiefMaster

1

None싱글 톤 이라는 John Machin의 결론 은이 코드에 의해 강화 된 결론입니다.

>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>> 

이후로는 None싱글 톤, x == None그리고 x is None같은 결과를 가질 것이다. 그러나 내 미적 견해로 x == None는 최고입니다.


2
이 답변의 끝에 의견에 동의하지 않습니다. 명시 적으로 없음과 비교할 때는 일반적으로 문제의 None객체 가 정확히 객체입니다. 비교해 볼 때, False다른 가치관이 진실 이라는 것을 제외하고 다른 맥락에서는 아무도 사용하지 않는 경우가 거의 없습니다 . 이 경우 다음과 같은 작업을 수행하는 것이 관용적입니다.if x: pass
SingleNegationElimination

0
a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.