"=="와 "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
테스트하여 동일한 객체인지 확인합니까?
is
True
두 변수가 동일한 객체를 가리키면 ==
변수가 참조하는 객체가 같으면 반환 됩니다 .
>>> 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에 대한 연산자
is
및is not
테스트 : 과 동일한 개체 인x is y
경우에만 true 입니다. 객체 ID는 함수를 사용하여 결정 됩니다. 역 진리 값을 산출합니다.x
y
id()
x is not y
따라서 ID 확인은 객체 ID의 동일성을 확인하는 것과 동일합니다. 그건,
a is b
와 같다:
id(a) == id(b)
여기서는 id
"동시에 존재하는 객체간에 고유함이 보장되는"정수를 반환하는 내장 함수이며 (참조 help(id)
) where a
and b
are any 임의의 객체입니다.
기타 사용법
의미론을 위해 이러한 비교를 사용해야합니다. 사용 is
의 신원을 확인하고 ==
평등을 확인 할 수 있습니다.
표준 라이브러리에 대한 공식 Python 스타일 가이드 인 PEP 8에는 다음에 대한 두 가지 사용 사례가is
언급 되어 있습니다 .
같은 싱글 톤에 대한 비교 는 항등 연산자가 아닌
None
항상is
또는 로 수행되어야합니다is not
.또한
if x
실제로 의미하는 경우 쓰기에주의하십시오.if x is not None
예를 들어 기본값None
으로 설정된 변수 또는 인수가 다른 값으로 설정 되었는지 여부를 테스트 할 때 . 다른 값은 부울 컨텍스트에서 거짓 일 수있는 유형 (예 : 컨테이너)을 가질 수 있습니다!
정체성에서 평등 추론
is
true 인 경우 일반적으로 동등성을 추론 할 수 있습니다. 논리적으로 객체가 자체 인 경우 자체와 동등한 것으로 테스트해야합니다.
대부분의 경우이 논리는 사실이지만 __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
다음 예에서 이름 value1
과 value2
참조는 int
둘 다 동일한 정수를 저장하더라도 다른 인스턴스를 참조합니다 .
>>> value1 = 1000
>>> value2 = 1000
저장되어있는 같은 값 (정수) 때문에 ==
것 True
, 그것은 종종 "값 비교"이라고 이유의 그. 그러나 이들은 다른 객체이기 때문에 is
반환 False
됩니다.
>>> value1 == value2
True
>>> value1 is value2
False
언제 사용합니까?
일반적으로 is
훨씬 빠른 비교입니다. 이것이 CPython이 작은 정수, 일부 문자열 등과 같은 특정 개체를 캐시 (또는 재사용 이 더 나은 용어 일 수 있음)하는 이유입니다 . 그러나 이것은 경고없이 언제라도 변경 될 수있는 구현 세부 사항 으로 처리되어야합니다 .
당신은해야 에만 사용is
하면 경우 :
- 두 객체가 실제로 동일한 객체인지 확인하려고합니다 (단지 동일한 "값"이 아님). 경우 한 가지 예는 될 수 는 상수로 싱글 톤 객체를 사용합니다.
값을 파이썬 상수 와 비교하고 싶습니다 . Python의 상수는 다음과 같습니다.
None
True
1False
1NotImplemented
Ellipsis
__debug__
- 클래스 (예 :
int is int
또는int is float
) - 내장 모듈 또는 타사 모듈에 추가 상수가있을 수 있습니다. 예를 들어
np.ma.masked
NumPy 모듈에서)
에서 다른 모든 경우에 당신은 사용해야==
평등을 확인 할 수 있습니다.
동작을 사용자 지정할 수 있습니까?
==
다른 답변에서 이미 언급되지 않은 몇 가지 측면이 있습니다 . 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) 할 수 있습니다, 그것은 반환에 국한되지 것 True
나 False
. 그것은 수 아무것도 반환 (그러나 대부분의 경우는 부울을 반환해야합니다!).
예를 들어 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으로 간주되지 않음)으로 제한됩니다.if
is 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
'developer tip' 카테고리의 다른 글
std :: string과 int를 연결하는 방법은 무엇입니까? (0) | 2020.10.02 |
---|---|
Bash에서 stderr 및 stdout 리디렉션 (0) | 2020.10.02 |
.NET에서 구조체와 클래스의 차이점은 무엇입니까? (0) | 2020.10.02 |
인쇄 미리보기 모드에서 Chrome의 요소 검사기를 사용하십니까? (0) | 2020.10.02 |
문자열이 숫자인지 식별 (0) | 2020.09.30 |