[python] id () 함수는 무엇에 사용됩니까?

Python 2 문서를 읽고 id()함수를 발견했습니다 .

객체의 “ID”를 반환합니다. 이는 수명 동안이 개체에 대해 고유하고 일정하게 보장되는 정수 (또는 긴 정수)입니다. 수명이 겹치지 않는 두 개체는 동일한 id () 값을 가질 수 있습니다.

CPython 구현 세부 사항 : 이것은 메모리에있는 오브젝트의 주소입니다.

그래서 id()목록 을 사용하여 실험했습니다 .

>>> list = [1,2,3]
>>> id(list[0])
31186196
>>> id(list[1])
31907092 // increased by 896
>>> id(list[2])
31907080 // decreased by 12

함수에서 반환 된 정수는 무엇입니까? C의 메모리 주소와 동의어입니까? 그렇다면 정수가 데이터 유형의 크기와 일치하지 않는 이유는 무엇입니까?

id()실제로 언제 사용됩니까?



답변

귀하의 게시물에는 몇 가지 질문이 있습니다.

함수에서 반환 된 숫자는 무엇입니까?

수명 동안이 객체에 대해 고유하고 상수가 보장되는 정수 (또는 긴 정수)입니다.(Python 표준 라이브러리-내장 함수) 고유 한 숫자입니다. 그 이상도 그 이하도 아닙니다. Python 객체에 대한 사회 보장 번호 또는 직원 ID 번호로 생각하십시오.

C의 메모리 주소와 동일합니까?

개념적으로는 그렇습니다. 둘 다 평생 동안 우주에서 독특함을 보장한다는 점에서 그렇습니다. 그리고 파이썬의 특정 구현에서는 실제로 해당 C 객체의 메모리 주소입니다.

그렇다면 데이터 유형의 크기만큼 숫자가 즉시 증가하지 않는 이유는 무엇입니까 (정수라고 가정합니다)?

목록은 배열이 아니고 목록 요소는 객체가 아니라 참조이기 때문입니다.

우리는 언제 실제로 id( )기능을 사용 합니까?

거의 없습니다. id()(또는 이에 상응하는) is연산자 가 사용됩니다 .


답변

그것은 메모리에있는 물체 의 위치 에 대한 정체입니다 .

이 예는 개념을 좀 더 이해하는 데 도움이 될 수 있습니다.

foo = 1
bar = foo
baz = bar
fii = 1

print id(foo)
print id(bar)
print id(baz)
print id(fii)

> 1532352
> 1532352
> 1532352
> 1532352

이들은 모두 메모리에서 동일한 위치를 가리 키므로 값이 동일한 것입니다. 이 예에서는 1한 번만 저장되며 다른 모든 항목 1은 해당 메모리 위치를 참조합니다.


답변

id()참조되는 객체의 주소를 반환하지만 (CPython에서) 파이썬 목록이 C 배열과 매우 다르다는 사실에서 혼란이 발생합니다. 파이썬 목록에서 모든 요소는 참조 입니다. 그래서 당신이하는 일은이 C 코드와 훨씬 더 비슷합니다.

int *arr[3];
arr[0] = malloc(sizeof(int));
*arr[0] = 1;
arr[1] = malloc(sizeof(int));
*arr[1] = 2;
arr[2] = malloc(sizeof(int));
*arr[2] = 3;
printf("%p %p %p", arr[0], arr[1], arr[2]);

즉,이 기준에서 주소와 인쇄 하지 목록이 저장되어있는 곳으로 주소 상대를.

필자의 경우 id()C python에서 호출 할 때 C 코드로 돌아가는 불투명 핸들을 만드는 데 편리한 함수를 찾았습니다 . 이렇게하면 사전을 사용하여 해당 핸들에서 객체를 쉽게 찾을 수 있으며 고유함이 보장됩니다.


답변

Rob의 대답 (위에서 가장 많이 투표)이 맞습니다. 어떤 상황에서는 ID를 사용하는 것이 개체를 비교하고 어떤 개체가 개체를 참조하는지 찾을 수 있기 때문에 유용하다는 점을 추가하고 싶습니다.

나중에는 일반적으로 변경 가능한 객체가 매개 변수로 전달되어 클래스를 말하고 클래스의 로컬 변수에 할당되는 이상한 버그를 디버그하는 데 도움이됩니다. 이러한 개체를 변경하면 클래스의 변수가 변경됩니다. 이것은 동시에 여러 가지가 변경되는 이상한 행동으로 나타납니다.

최근에 한 텍스트 입력 필드의 텍스트를 편집하면 입력 한대로 다른 텍스트를 변경하는 Python / Tkinter 앱에서이 문제가 발생했습니다. 🙂

다음은 해당 참조가있는 위치를 추적하기 위해 함수 id ()를 사용하는 방법에 대한 예입니다. 이것은 가능한 모든 경우를 포괄하는 솔루션은 아니지만 아이디어를 얻을 수 있습니다. 다시 ID는 백그라운드에서 사용되며 사용자는이를 볼 수 없습니다.

class democlass:
    classvar = 24

    def __init__(self, var):
        self.instancevar1 = var
        self.instancevar2 = 42

    def whoreferencesmylocalvars(self, fromwhere):
        return {__l__: {__g__
                    for __g__ in fromwhere
                        if not callable(__g__) and id(eval(__g__)) == id(getattr(self,__l__))
                    }
                for __l__ in dir(self)
                    if not callable(getattr(self, __l__)) and __l__[-1] != '_'
                }

    def whoreferencesthisclassinstance(self, fromwhere):
        return {__g__
                    for __g__ in fromwhere
                        if not callable(__g__) and id(eval(__g__)) == id(self)
                }

a = [1,2,3,4]
b = a
c = b
democlassinstance = democlass(a)
d = democlassinstance
e = d
f = democlassinstance.classvar
g = democlassinstance.instancevar2

print( 'My class instance is of', type(democlassinstance), 'type.')
print( 'My instance vars are referenced by:', democlassinstance.whoreferencesmylocalvars(globals()) )
print( 'My class instance is referenced by:', democlassinstance.whoreferencesthisclassinstance(globals()) )

산출:

My class instance is of <class '__main__.democlass'> type.
My instance vars are referenced by: {'instancevar2': {'g'}, 'classvar': {'f'}, 'instancevar1': {'a', 'c', 'b'}}
My class instance is referenced by: {'e', 'd', 'democlassinstance'}

변수 이름의 밑줄은 이름 충돌을 방지하는 데 사용됩니다. 함수는 “fromwhere”인수를 사용하므로 참조 검색을 시작할 위치를 알 수 있습니다. 이 인수는 주어진 네임 스페이스의 모든 이름을 나열하는 함수로 채워집니다. Globals ()는 그러한 함수 중 하나입니다.


답변

나는 파이썬으로 시작하고 있으며 대화 형 쉘을 사용할 때 내 변수가 동일한 것에 할당되었는지 또는 동일하게 보이는지 확인하기 위해 id를 사용합니다.

모든 값은 컴퓨터의 메모리에 저장된 위치와 관련된 고유 번호 인 ID입니다.


답변

python 3.4.1을 사용하는 경우 질문에 대한 다른 답변을 얻을 수 있습니다.

list = [1,2,3]
id(list[0])
id(list[1])
id(list[2])

보고:

1705950792
1705950808  # increased by 16   
1705950824  # increased by 16

정수 는 상수 ID -5256가지며 여러 번 찾을 때마다 ID가 다른 다른 모든 숫자와 달리 ID가 변경되지 않습니다. 에서 오는 숫자 는 오름차순으로 ID -5256가지며 16.

id()함수가 반환하는 숫자는 메모리에 저장된 각 항목에 부여 된 고유 한 ID이며 C의 메모리 위치와 유사합니다.


답변

대답은 거의 없습니다. ID는 주로 Python 내부에서 사용됩니다.

평균적인 파이썬 프로그래머는 아마도 id()코드에서 사용할 필요가 없을 것입니다 .