>  기사  >  백엔드 개발  >  Python에는 is와 id가 무엇입니까?

Python에는 is와 id가 무엇입니까?

巴扎黑
巴扎黑원래의
2017-04-30 16:28:491919검색

(ob1은 ob2입니다)는 (id(ob1) == id(ob2))

와 동일합니다. 첫째, id 함수는 객체의 메모리 주소를 가져올 수 있습니다. 두 객체의 메모리 주소가 동일하면 두 객체는 ​​하나의 객체여야 합니다. is와 동일합니다. 증거로 사용되는 Python 소스 코드.

아아아아

​그런데 아래 코드에서 이런 상황이 어떻게 발생하는지 살펴볼까요?

아아아아

두 개체는 is를 사용하여 False로 판단하지만 id를 사용하여 판단하면 True입니다. 이는 우리가 알고 있는 사실과 일치하지 않습니다. 이 상황에 대한 가장 좋은 해결책은 dis 모듈을 호출하여 두 비교 문이 수행하는 작업을 확인하는 것입니다.

아아아아

실제 상황은 .연산자가 실행되면 실제로 프록시 객체가 생성되는데, foo.bar가 Foo.bar이면 두 객체가 순차적으로 생성되어 비교를 위해 스택에 배치됩니다. False이지만 id(foo.bar) == id(Foo.bar)인 경우에는 다릅니다. 먼저 foo.bar가 생성된 후 foo.bar의 주소가 계산됩니다. , foo.bar를 가리키는 개체가 없으므로 foo.bar 개체가 해제됩니다. 그런 다음 Foo.bar 객체를 생성합니다. foo.bar와 Foo.bar는 동일한 메모리 크기를 차지하므로 원래 foo.bar의 메모리 주소가 재사용되므로 id(foo.bar) == id(Foo.bar )은 참입니다.

다음 내용은 Leo Jay가 이메일을 통해 더 명확하게 설명합니다.

두 표현식의 결과가 동일한 객체인지 확인하기 위해 id(expression a) == id(expression b)를 사용한다는 아이디어는 문제가 있습니다.

이런 형태의 foo.bar를 속성 참조[1]라고 하는데 이는 표현식의 일종이다. foo는 인스턴스 객체이고, bar는 메소드이다. 이때 foo.bar 표현식이 반환한 결과를 메소드 객체라고 한다[2]. 문서에 따르면:

으르르

foo.bar 자체는 단순한 이름이 아니라 메소드 객체인 표현식의 계산 결과입니다. id(foo.bar)와 같은 표현식에서 메소드 객체는 단지 임시 중간 변수일 뿐입니다. 변수를 ID로 사용합니다.

더 확실한 예는

static PyObject *
 cmp_outcome(int op, register PyObject *v, register PyObject *w)
{
 int res = 0;
 switch (op) {
 case PyCmp_IS:
  res = (v == w);
 break;
 case PyCmp_IS_NOT:
res = (v != w);
 break;

입니다. 출력 결과도 True

​id[3] 문서를 살펴보세요.

으르르

객체가 파괴되지 않을 것이라고 보장할 수 있는 경우에만 id를 사용하여 두 객체를 비교할 수 있습니다. 그러니 꼭 비교를 하려고 한다면 다음과 같이 써야 합니다:

In [1]: def bar(self, x):
...:     return self.x + y
...: 

In [2]: class Foo(object):
...:     x = 9
...:     def __init__(self ,x):
...:         self.x = x
...:     bar = bar
...:     

In [3]: foo = Foo(5)

In [4]: foo.bar is Foo.bar
Out[4]: False

In [5]: id(foo.bar) == id(Foo.bar)
Out[5]: True

즉, 두 표현식의 결과를 이름에 바인딩한 후 동일한 객체인지 비교하면 올바른 결과를 얻을 수 있습니다.

is 표현식 [4]의 경우에도 마찬가지입니다. 지금 얻는 올바른 결과는 전적으로 CPython의 현재 구현 세부 사항 때문입니다. is의 현재 구현은 왼쪽과 오른쪽의 개체를 계산한 다음 두 개체의 주소가 동일한지 비교하는 것입니다. 언젠가 바뀌게 된다면 왼쪽을 먼저 계산하고 주소를 저장하고 왼쪽을 놓은 후 오른쪽을 계산하고 다시 비교해보면 자신의 결과가 틀릴 수도 있습니다. 이 문제는 공식 문서 [5]에도 언급되어 있습니다. 올바른 방법은 id와 같아서 먼저 왼쪽과 오른쪽을 모두 계산하고 명시적으로 각각의 이름에 바인딩한 다음 판단하는 것입니다.

[1] http://docs.python.org/2/reference/expressions.html#attribute-references
[2] http://docs.python.org/2/tutorial/classes.html#method-objects
[3] http://docs.python.org/2/library/functions.html#id
[4] http://docs.python.org/2/reference/expressions.html#index-68
[5] http://docs.python.org/2/reference/expressions.html#id26

위 내용은 Python에는 is와 id가 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.