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 -5
를 256
가지며 여러 번 찾을 때마다 ID가 다른 다른 모든 숫자와 달리 ID가 변경되지 않습니다. 에서 오는 숫자 는 오름차순으로 ID -5
를 256
가지며 16
.
id()
함수가 반환하는 숫자는 메모리에 저장된 각 항목에 부여 된 고유 한 ID이며 C의 메모리 위치와 유사합니다.
답변
대답은 거의 없습니다. ID는 주로 Python 내부에서 사용됩니다.
평균적인 파이썬 프로그래머는 아마도 id()
코드에서 사용할 필요가 없을 것입니다 .