什么是id()函数用于?

我读了Python 2文档,并注意到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中的内存地址是同义词吗? 如果是这样,为什么整数不对应数据types的大小?

id()用在实践中?

您的post提出了几个问题:

从函数返回的数字是多less?

它是“ 一个整数(或长整型),在其生命周期中保证这个对象是唯一且恒定的。 ” (Python标准库 – 内置函数)一个唯一的数字。 没有更多,也没有less。 将其视为Python对象的社会安全号码或员工身份号码。

与C中的内存地址是一样的吗?

从概念上说,是的,因为它们在一生中都保证它们在宇宙中是独一无二的。 在Python的一个特定实现中,它实际上是相应C对象的内存地址。

如果是的话,为什么这个数字不会立即增加数据types的大小(我认为它会是int)?

因为列表不是一个数组,列表元素是一个引用,而不是一个对象。

我们什么时候真的使用id( )函数?

几乎没有。 在is运算符中使用id() (或其等价物)。

这是对象在内存中的位置的标识…

这个例子可能会帮助你更多地理解这个概念。

 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中),但是你的困惑来自于python列表与C数组非常不同的事实。 在一个python列表中,每个元素都是一个引用 。 所以你正在做的是更类似于这个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()函数可以方便地创build不透明句柄,以便在从C中调用python时返回C代码。这样做可以很容易地使用字典从句柄中查找对象,并且保证独特。

我开始与python和我使用id时,我使用交互式shell来查看我的variables是分配给相同的东西,或者他们只是看起来相同。

每个值都是一个id,它是一个唯一的数字,与它存储在计算机内存中的位置有关。

这是内存中的对象的地址,正如文档所说。 然而,它具有附加的元数据,对象的属性和存储器中的位置需要存储元数据。 所以,当你创build名为list的variables的时候,你还可以为列表及其元素创build元数据。

所以,除非你是语言上的绝对权威,否则你不能根据前一个元素来确定你的列表中下一个元素的id,因为你不知道这个语言与元素一起分配了什么。

答案是从来没有。 ID主要在Python内部使用。

普通的Python程序员可能永远不需要在他们的代码中使用id()

is运算符使用它来检查两个对象是否相同(相当于相等)。 从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

整数-5到256有一个不变的id,并且多次发现它的id不会改变,不同于之前或之后的所有其他数字,每当你findid时都有不同的id。 从-5到256的数字具有递增的顺序,相差16。

由id()函数返回的数字是存储在内存中的每个项目的唯一ID,它与C中的内存位置类似。

罗布的答案(上面大多数投票)是正确的。 我想补充一点,在某些情况下使用ID是有用的,因为它允许比较对象并找出哪些对象引用了你的对象。

后者通常可以帮助你debugging可变对象作为parameter passing给类的奇怪的错误,并被分配给类中的本地variables。 突变这些对象会改变class级中的variables。 这performance在多个事物同时变化的奇怪行为中。

最近我遇到了一个Python / Tkinter应用程序的问题,在一个文本input字段中编辑文本改变了另一个文本,因为我键入:)

这里是一个关于如何使用函数id()来跟踪那些引用的地方的例子。 无论如何,这不是涵盖所有可能情况的解决scheme,但你明白了。 再次在后台使用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()) ) 

OUTPUT:

 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'} 

variables名中的下划线用于防止名称变形。 函数使用“fromwhere”参数,以便让他们知道从哪里开始search引用。 这个参数由一个列出给定名字空间中的所有名字的函数填充。 全局()是一个这样的function。

我有一个想法,在日志中使用id()的值。 这很便宜,而且很短。 在我的情况下,我使用龙卷风和ID()想有一个锚点,以分散和混合文件通过networking套接字的消息。