developer tip

"=="와 "is"사이에 차이가 있습니까?

copycodes 2020. 10. 2. 22:48
반응형

"=="와 "is"사이에 차이가 있습니까?


Google-fu 가 실패했습니다.

Python에서 동등성에 대한 다음 두 가지 테스트가 동일합니까?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

인스턴스를 비교하는 객체에 대해서도 마찬가지 list입니까 ( 말)?

좋아요, 이런 종류의 질문에 대한 답이 있습니다.

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

그렇다면 ==테스트 값을 is테스트하여 동일한 객체인지 확인합니까?


isTrue두 변수가 동일한 객체를 가리키면 ==변수가 참조하는 객체가 같으면 반환 됩니다 .

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:] # Make a new copy of list `a` via the slice operator, and assign it to variable `b`
>>> b is a
False
>>> b == a
True

귀하의 경우 두 번째 테스트는 Python이 구현 세부 사항 인 작은 정수 객체를 캐시하기 때문에 작동합니다. 더 큰 정수의 경우 작동하지 않습니다.

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

문자열 리터럴도 마찬가지입니다.

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

이 질문참조하십시오 .


==또는 을 사용할 때를 알려주는 간단한 경험 법칙이 있습니다 is.

  • ==가치 평등을 위한 것 입니다. 두 개체의 값이 같은지 알고 싶을 때 사용합니다.
  • is을위한 참조 평등 . 두 참조가 동일한 객체를 참조하는지 알고 싶을 때 사용합니다.

일반적으로 어떤 것을 단순한 유형과 비교할 때 일반적으로 값이 같은지 확인 하므로을 사용해야합니다 ==. 예를 들어, 예제의 의도 는 문자 그대로 2와 동일한 객체를 참조 ==하는지 여부 x아니라 x의 값이 2 ( )인지 확인하는 것 입니다.


참고할 사항 : CPython 참조 구현이 작동하는 방식으로 인해 is정수에 대한 참조 동등성을 비교 하는 실수로 사용하면 예상치 못한 일관성없는 결과를 얻을 수 있습니다 .

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

그것은 우리가 기대했던 것입니다. a그리고 b같은 가치를 가지고 있지만 별개의 개체입니다. 하지만 이것은 어떻습니까?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

이것은 이전 결과와 일치하지 않습니다. 여기서 무슨 일이 일어나고 있습니까? 파이썬의 참조 구현은 성능상의 이유로 -5..256 범위의 정수 객체를 싱글 톤 인스턴스로 캐시합니다. 이를 보여주는 예는 다음과 같습니다.

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

이것은 사용하지 않는 또 다른 명백한 이유 is입니다. 값 평등을 위해 잘못 사용하는 경우 동작은 구현에 달려 있습니다.


==값이 동일한 지 여부를 확인하고, 값이 is정확히 동일한 객체이고 동일한 지 확인합니다.


파이썬에서 ==사이에 차이점이 is있습니까?

예, 그들은 매우 중요한 차이가 있습니다.

==: 동등성 확인-의미는 동등한 객체 (동일한 객체 일 필요는 없음)가 동일한 것으로 테스트된다는 것입니다. 현상태대로 설명서를 말한다 :

연산자 <,>, ==,> =, <= 및! =는 두 개체의 값을 비교합니다.

is: 신원 확인-의미는 객체 (메모리에 보관 된) 객체라는 것입니다. 다시 말하지만, 문서는 다음 과 같이 말합니다 .

개체 ID에 대한 연산자 isis not테스트 : 동일한 개체 인 x is y경우에만 true 입니다. 객체 ID는 함수를 사용하여 결정 됩니다. 역 진리 값을 산출합니다.xyid()x is not y

따라서 ID 확인은 객체 ID의 동일성을 확인하는 것과 동일합니다. 그건,

a is b

와 같다:

id(a) == id(b)

여기서는 id"동시에 존재하는 객체간에 고유함이 보장되는"정수를 반환하는 내장 함수이며 (참조 help(id)) where aand bare any 임의의 객체입니다.

기타 사용법

의미론을 위해 이러한 비교를 사용해야합니다. 사용 is의 신원을 확인하고 ==평등을 확인 할 수 있습니다.

표준 라이브러리에 대한 공식 Python 스타일 가이드 인 PEP 8에는 다음에 대한 두 가지 사용 사례가is 언급 되어 있습니다 .

같은 싱글 톤에 대한 비교 는 항등 연산자가 아닌 None항상 is또는 로 수행되어야합니다 is not.

또한 if x실제로 의미하는 경우 쓰기에주의하십시오. if x is not None예를 들어 기본값 None으로 설정된 변수 또는 인수가 다른 값으로 설정 되었는지 여부를 테스트 할 때 . 다른 값은 부울 컨텍스트에서 거짓 일 수있는 유형 (예 : 컨테이너)을 가질 수 있습니다!

정체성에서 평등 추론

istrue 인 경우 일반적으로 동등성을 추론 할 수 있습니다. 논리적으로 객체가 자체 인 경우 자체와 동등한 것으로 테스트해야합니다.

대부분의 경우이 논리는 사실이지만 __eq__특수 메서드 의 구현에 의존합니다 . 는 AS 문서는 말한다,

같음 비교 ( ==!=) 의 기본 동작 은 개체의 ID를 기반으로합니다. 따라서 동일한 ID를 가진 인스턴스의 동등 비교는 동등성을 가져오고 다른 ID를 가진 인스턴스의 동등 비교는 불평등을 초래합니다. 이 기본 동작의 동기는 모든 객체가 반사적이어야한다는 것입니다 (즉, x는 y는 x == y를 의미 함).

일관성을 위해 다음을 권장합니다.

동등 비교는 재귀 적이어야합니다. 즉, 동일한 객체는 동일하게 비교되어야합니다.

x is y 암시 x == y

이것이 사용자 지정 개체의 기본 동작임을 알 수 있습니다.

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

반대의 경우도 일반적으로 사실입니다. 어떤 것이 동일하지 않은 것으로 테스트되면 일반적으로 동일한 대상이 아니라고 추론 할 수 있습니다.

동등성 테스트는 사용자 정의 할 수 있으므로이 추론이 모든 유형에 대해 항상 적용되는 것은 아닙니다.

예외

주목할만한 예외는 nan-항상 자신과 같지 않은 것으로 테스트합니다.

>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False

신원을 확인하는 것은 동등성을 확인하는 것보다 훨씬 더 빠르게 확인할 수 있습니다 (멤버를 재귀 적으로 확인해야 할 수도 있음).

그러나 둘 이상의 객체를 동등하게 찾을 수있는 동등성을 대체 할 수 없습니다.

리스트와 튜플의 동일성을 비교하면 객체의 신원이 동일하다고 가정합니다 (빠른 검사이기 때문에). 논리가 일치하지 않으면 모순이 발생할 수 있습니다 nan.

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

주의 이야기 :

질문은 is정수를 비교하는 데 사용하려고합니다 . 정수의 인스턴스가 다른 참조에서 얻은 인스턴스와 동일한 인스턴스라고 가정해서는 안됩니다. 이 이야기는 그 이유를 설명합니다.

한 주석 작성자는 작은 정수 (-5에서 256까지 포함)가 동등성을 확인하는 대신 Python에서 싱글 톤이라는 사실에 의존하는 코드를 가졌습니다.

와우, 이것은 교활한 버그로 이어질 수 있습니다. a와 b가 일반적으로 작은 숫자이기 때문에 원하는대로 작동하는 a가 b인지 확인하는 코드가 있습니다. 버그는 생산에서 6 개월이 지난 오늘만 발생했습니다. a와 b가 마침내 캐시되지 않을만큼 충분히 커졌기 때문입니다. – gwg

그것은 개발 중에 작동했습니다. 일부 단위 테스트를 통과했을 수 있습니다.

그리고 프로덕션에서 작동했습니다. 코드가 256보다 큰 정수를 확인하기 전까지는 프로덕션에서 실패했습니다.

이것은 코드 검토 또는 스타일 검사기에서 발견 될 수있는 프로덕션 실패입니다.

강조하겠습니다 : 정수를 비교 하는 is사용하지 마십시오 .


is의 차이점은 무엇입니까 ==?

==그리고 is다른 비교입니다! 다른 사람들이 이미 말했듯이 :

  • == 개체의 값을 비교합니다.
  • is 개체의 참조를 비교합니다.

파이썬 이름이 경우, 예를 들어, 개체 참조 value1하고 value2참조 int값을 저장하는 경우 1000:

value1 = 1000
value2 = value1

여기에 이미지 설명 입력

때문에이 value2같은 객체를 참조 is하고 ==줄 것이다 True:

>>> value1 == value2
True
>>> value1 is value2
True

다음 예에서 이름 value1value2참조는 int둘 다 동일한 정수를 저장하더라도 다른 인스턴스를 참조합니다 .

>>> value1 = 1000
>>> value2 = 1000

여기에 이미지 설명 입력

저장되어있는 같은 값 (정수) 때문에 ==True, 그것은 종종 "값 비교"이라고 이유의 그. 그러나 이들은 다른 객체이기 때문에 is반환 False됩니다.

>>> value1 == value2
True
>>> value1 is value2
False

언제 사용합니까?

일반적으로 is훨씬 빠른 비교입니다. 이것이 CPython이 작은 정수, 일부 문자열 등과 같은 특정 개체를 캐시 (또는 재사용 이 더 나은 용어 일 수 있음)하는 이유입니다 . 그러나 이것은 경고없이 언제라도 변경 될 수있는 구현 세부 사항 으로 처리되어야합니다 .

당신은해야 에만 사용is 하면 경우 :

  • 두 객체가 실제로 동일한 객체인지 확인하려고합니다 (단지 동일한 "값"이 아님). 경우 한 가지 예는 될 수 상수로 싱글 톤 객체를 사용합니다.
  • 값을 파이썬 상수 와 비교하고 싶습니다 . Python의 상수는 다음과 같습니다.

    • None
    • True1
    • False1
    • NotImplemented
    • Ellipsis
    • __debug__
    • 클래스 (예 : int is int또는 int is float)
    • 내장 모듈 또는 타사 모듈에 추가 상수가있을 수 있습니다. 예를 들어 np.ma.maskedNumPy 모듈에서)

에서 다른 모든 경우에 당신은 사용해야== 평등을 확인 할 수 있습니다.

동작을 사용자 지정할 수 있습니까?

==다른 답변에서 이미 언급되지 않은 몇 가지 측면이 있습니다 . Pythons "Data model" 의 일부입니다 . 즉, __eq__메서드를 사용하여 동작을 사용자 지정할 수 있습니다 . 예를 들면 :

class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))

이것은 메서드가 실제로 호출되었음을 설명하는 인위적인 예일뿐입니다.

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

기본적으로 ( __eq__클래스 나 수퍼 클래스에서의 다른 구현을 찾을 수 없는 경우 ) 다음을 __eq__사용합니다 is.

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

따라서 __eq__사용자 정의 클래스에 대한 참조 비교보다 "더 많은"것을 원한다면 구현 하는 것이 실제로 중요합니다 !

반면에 is검사를 사용자 정의 할 수 없습니다 . 항상 비교합니다 단지 동일한 기준이있는 경우.

이러한 비교는 항상 부울을 반환합니까?

때문에 __eq__재 구현 또는 오버라이드 (override) 할 수 있습니다, 그것은 반환에 국한되지 것 TrueFalse. 그것은 아무것도 반환 (그러나 대부분의 경우는 부울을 반환해야합니다!).

예를 들어 NumPy 배열을 사용하면 배열 ==이 반환됩니다.

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

그러나 is수표는 항상 True또는 False!


1 Aaron Hall이 의견에서 언급했듯이 :

일반적으로 조건암시 적으로 부울 로 변환하는 컨텍스트 (예 : 문) 에서 이러한 "검사"를 일반적으로 사용하기 때문에 is True또는 is False검사를 수행해서는 안됩니다 . 따라서 비교 암시 적 부울 캐스트를 수행하는 것은 단순히 부울 캐스트를 수행하는 것보다 더 많은 작업을 수행합니다. 그리고 부울 (pythonic으로 간주되지 않음)으로 제한됩니다.ifis True

PEP8 언급처럼 :

부울 값을 비교하지 마십시오 True또는 False사용 ==.

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

그들은 완전히 다릅니다 . is객체 ID를 ==확인하고 동등성 확인합니다 (두 피연산자의 유형에 따라 달라지는 개념).

" is"이 작은 정수 (예 : 5 == 4 + 1)로 올바르게 작동하는 것처럼 보이는 것은 운이 좋은 우연 일뿐 입니다. CPython은 정수를 싱글 톤으로 만들어 범위 (-5 ~ 256)의 정수 저장을 최적화 하기 때문 입니다. 이 동작은 완전히 구현에 따라 다르며 모든 사소한 변형 작업에서 보존되지 않을 수도 있습니다.

예를 들어 Python 3.5는 짧은 문자열도 싱글 톤으로 만들지 만 슬라이스하면이 동작이 중단됩니다.

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

https://docs.python.org/library/stdtypes.html#comparisons

is동일성에 대한 신원 ==테스트

Each (small) integer value is mapped to a single value, so every 3 is identical and equal. This is an implementation detail, not part of the language spec though


Your answer is correct. The is operator compares the identity of two objects. The == operator compares the values of two objects.

An object's identity never changes once it has been created; you may think of it as the object's address in memory.

You can control comparison behaviour of object values by defining a __cmp__ method or a rich comparison method like __eq__.


Have a look at Stack Overflow question Python's “is” operator behaves unexpectedly with integers.

What it mostly boils down to is that "is" checks to see if they are the same object, not just equal to each other (the numbers below 256 are a special case).


As John Feminella said, most of the time you will use == and != because your objective is to compare values. I'd just like to categorise what you would do the rest of the time:

There is one and only one instance of NoneType i.e. None is a singleton. Consequently foo == None and foo is None mean the same. However the is test is faster and the Pythonic convention is to use foo is None.

If you are doing some introspection or mucking about with garbage collection or checking whether your custom-built string interning gadget is working or suchlike, then you probably have a use-case for foo is bar.

True and False are also (now) singletons, but there is no use-case for foo == True and no use case for foo is True.


Most of them already answered to the point. Just as an additional note (based on my understanding and experimenting but not from a documented source), the statement

== if the objects referred to by the variables are equal

from above answers should be read as

== if the objects referred to by the variables are equal and objects belonging to the same type/class

. I arrived at this conclusion based on the below test:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

Here the contents of the list and tuple are same but the type/class are different.


In a nutshell, is checks whether two references point to the same object or not.== checks whether two objects have the same value or not.

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

Actually I wanted to add this as a comment but could not beautify it easily hence adding as an answer, please do not consider this as an answer.

This is what I did to understand --

execute following one by one and understand output on every step

a = [1,2]
b = [1,2,3]
b.pop()
id(a)
id(b)
a is b
a == b

As the other people in this post answer the question in details, I would emphasize mainly the comparison between is and == for strings which can give different results and I would urge programmers to carefully use them.

For string comparison, make sure to use == instead of is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Out:

str is hello
str == hello

But in the below example == and is will get different results:

str = 'hello sam'
    if (str is 'hello sam'):
        print ('str is hello sam')
    if (str == 'hello sam'):
        print ('str == hello sam')

Out:

str == hello sam

Conclusion:

Use is carefully to compare between strings


Python difference between is and equals(==)

is 연산자는 같음 연산자와 동일하게 보일 수 있지만 동일하지 않습니다.

는 두 변수가 동일한 객체를 가리키는 지 확인하는 반면 == 기호는 두 변수의 값이 동일한 지 확인합니다.

따라서 is 연산자가 True를 반환하면 같음은 확실히 True이지만 그 반대는 True 일 수도 있고 아닐 수도 있습니다.

다음은 유사성과 차이점을 보여주는 예입니다.

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.

참고 URL : https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is

반응형